《Java数据结构和算法》第二版 Robert lafore 编程作业 第八章

来源:互联网 发布:caffe训练mnist 详解 编辑:程序博客网 时间:2024/05/23 15:40

《Java数据结构和算法》第二版 Robert lafore  编程作业 第八章

/* 编程作业  8.1从tree.java程序(清单8.1)出发,把它修改成用用户输入的字母的 字符串建立二叉树(如A、B等等),每个字母在各自的节点中显示。 建立树,让每个包含字母的节点是叶节点。父节点可以有非字母标志 如'+'。保证每个父节点都恰好有两个子节点。不要担心树不平衡。 注意这不是搜索树;没有快速的方法来查找节点。最后结果可以像下 面所示的一样:                        +                                                                                   +                              E                                        +              D              --              --                    +      C      --      --      --      --      --      --        A  B  --  --  --  --  --  --  --  --  --  --  --  --  --  --  一种方法是建立一个树的数组。(一组没有连接的树称为森林。)用  用户输入的每个字母作为一个节点。把每个节点作为一棵树,节点就  是根。现在把这些单节点的树放到数组中。下面开始建立一棵以'+'  为根的树,两个单节点树为它的子节点。依次把数组中的单节点树加  到这棵大点的树中。不要担心它是不是平衡树。实际可以用生成的中  间树覆盖数组单元,该数组单元的内容已经加到树中。find()、  insert()和delete()例程只用于搜索树,可以删掉了。保留  displayTree()方法和遍历方法,它们对所有二叉树都通用。  8.2 扩展编程作业8.1中的功能来创建平衡树。一种方法是保证节点尽可  能出现在最底层。开始把每对单节点树建成三节点树,以'+'为根。  这样就有一个三节点树的森林了。合并每对三节点树变成七点节点树  的森林。随着每棵树节点数目的增加,树的数量减少,直到最后只有  一棵树。  8.3还是从tree.java程序开始。根据用户输入的字符创建树。这次,建  立完全树--除了底层的最右边可能为空,其它层节点完全满的树。字  母要从上到下以及从左到右有序,好像就是建立了一个字符的金字塔。  (这种排列方法与本章前面讨论的三种遍历方法都不对应。)因此,  字符串ABCDEFGHIJ会排列成下面的样子:                       A                                                                          B                              C                                  D              E              F              G              H      I      J      --      --      --      --      --   建立这种树的一种方法是从上到下,而不是像编程作业中前两题那样从底向上。从建立一个作为最后树的根的节点开始。如果节点编号和字母排顺序一样,1是根,则编号为n的节点的左子节点的编号为2*n+1。可以用递归方法,创建两个了节点并在每个子节点中调用它自己的。节点创建的顺序不需要和它们插入到树中的顺序相同。像编程作业中前面的题那样,可以删掉Tree类中搜索树的一些方法。  8.4编写程序根据后缀表达式建立树,如本章图8.11中所示。需要修改  tree.java程序(清单8.1)中的Tree类,和第4单postfix.java程序  (清单4.8)中的ParsePost类。更多细节参考图8.11的解。建好树之后,  遍历树可以得到算术表达式相应的前缀、中缀和后缀表达式。中缀表达  式需要小括号来避免产生模糊不清的表达式。InOrder()方法中,在第  一次递归调用之前加入左括号,在第二次递归调用之后加入右括号。  8.5编写程序实现哈夫曼编码和解码。需要做如下的工作:  Accept a text message,possibly of more than one line.  Create a Huffman tree for this message.  Create a code table.  Encode the message into binary.  Decode the message from binary back to text.  如果信息很短,程序可以显示建立好的哈夫曼树。编程作业8.1、8.2  和8.3的方法会有所帮助的。可以用String变量把二进制数存储为字  符1和0的序列。除非确有必要,否则不需要做实际的位处理。 */package chap08;// tree.java// demonstrates binary tree// to run this program: C>java TreeAppimport java.io.*;import java.util.*;               // for Stack class////////////////////////////////////////////////////////////////class Node {public char cchar;public Node leftChild;         // this node's left childpublic Node rightChild;        // this node's right childpublic Node() {}public Node(char c) {cchar = c;}public void displayNode()      // display ourself{System.out.print('{');System.out.print(cchar);System.out.print("} ");}}  // end class Node// //////////////////////////////////////////////////////////////class Tree implements Comparable {// 改成了publicpublic Node root;             // first node of treepublic int weight; // 权重// -------------------------------------------------------------public Tree()                  // constructor{root = null;}            // no nodes in tree yet// 添加了toString()方法public String toString() {return root.cchar + "";}// -------------------------------------------------------------public void traverse(int traverseType) {switch (traverseType) {case 1:System.out.print("\nPreorder traversal: ");preOrder(root);break;case 2:System.out.print("\nInorder traversal:  ");inOrder(root);break;case 3:System.out.print("\nPostorder traversal: ");postOrder(root);break;}System.out.println();}// -------------------------------------------------------------private void preOrder(Node localRoot) {if (localRoot != null) {System.out.print(localRoot.cchar + " ");preOrder(localRoot.leftChild);preOrder(localRoot.rightChild);}}// -------------------------------------------------------------private void inOrder(Node localRoot) {if (localRoot != null) {System.out.print("(");inOrder(localRoot.leftChild);System.out.print(localRoot.cchar + " ");inOrder(localRoot.rightChild);System.out.print(")");}}// -------------------------------------------------------------private void postOrder(Node localRoot) {if (localRoot != null) {postOrder(localRoot.leftChild);postOrder(localRoot.rightChild);System.out.print(localRoot.cchar + " ");}}// -------------------------------------------------------------public void displayTree() {Stack globalStack = new Stack();globalStack.push(root);int nBlanks = 32;boolean isRowEmpty = false;System.out.println("......................................................");while (isRowEmpty == false) {Stack localStack = new Stack();isRowEmpty = true;for (int j = 0; j < nBlanks; j++)System.out.print(' ');while (globalStack.isEmpty() == false) {Node temp = (Node) globalStack.pop();if (temp != null) {System.out.print(temp.cchar);localStack.push(temp.leftChild);localStack.push(temp.rightChild);if (temp.leftChild != null || temp.rightChild != null)isRowEmpty = false;} else {System.out.print("--");localStack.push(null);localStack.push(null);}for (int j = 0; j < nBlanks * 2 - 2; j++)System.out.print(' ');}  // end while globalStack not emptySystem.out.println();nBlanks /= 2;while (localStack.isEmpty() == false)globalStack.push(localStack.pop());}  // end while isRowEmpty is falseSystem.out.println("......................................................");}  // end displayTree()// -------------------------------------------------------------@Overridepublic int compareTo(Object o) {if (o == null) {return -1;}return weight - ((Tree) o).weight;}}  // end class Tree// //////////////////////////////////////////////////////////////public class TreeApp {// 编程作业 8.1public static void code8_1() throws IOException {System.out.println("请输入至少字符串(至少两个字符):");String str = getString();Tree[] array = new Tree[str.length()];for (int i = 0; i < str.length(); i++) {// 建立单节点树数组Tree temp = new Tree();temp.root = new Node(str.charAt(i));array[i] = temp;}for (int i = 1; i < str.length(); i++) {Tree temp = new Tree();temp.root = new Node('+');temp.root.leftChild = array[i - 1].root;temp.root.rightChild = array[i].root;array[i] = temp;}Tree lastTree = array[str.length() - 1];lastTree.displayTree();}// 编程作业 8.2// 这是按题目8.2要求来的平衡二叉树public static void code8_2() throws IOException {System.out.println("请输入至少字符串(至少两个字符):");String str = getString();Tree[] array = new Tree[str.length()];for (int i = 0; i < array.length; i++) {// 建立单节点树数组Tree temp = new Tree();temp.root = new Node(str.charAt(i));array[i] = temp;}Tree[] tempArray;while (array.length > 1) {tempArray = new Tree[(array.length - 1) / 2 + 1];int j = -1;int i = 0;for (; i + 1 < array.length; i += 2) {Tree temp = new Tree();temp.root = new Node('+');temp.root.leftChild = array[i].root;temp.root.rightChild = array[i + 1].root;tempArray[++j] = temp;}if (i < array.length) {Tree temp = new Tree();temp.root = new Node('+');temp.root.leftChild = array[array.length - 1].root;tempArray[++j] = temp;// tempArray[++j] = array[i];}array = tempArray;}Tree lastTree = array[array.length - 1];lastTree.displayTree();}// 编程作业 8.2// 这才是真正的平衡二叉树public static void code8_2_1() throws IOException {System.out.println("请输入至少字符串(至少两个字符):");String str = getString();Tree[] array = new Tree[str.length()];for (int i = 0; i < array.length; i++) {// 建立单节点树数组Tree temp = new Tree();temp.root = new Node(str.charAt(i));array[i] = temp;}Tree lastTree = connectTree(array, 0, array.length - 1);lastTree.displayTree();}private static Tree connectTree(Tree[] array, int left, int right) {if (left == right) {return array[left];} else {Tree tempTree = new Tree();tempTree.root = new Node('+');tempTree.root.leftChild = connectTree(array, left,(right + left) / 2).root;tempTree.root.rightChild = connectTree(array,(right + left) / 2 + 1, right).root;return tempTree;}}// 编程作业 8.3public static void code8_3() throws IOException {System.out.println("请输入至少字符串(至少两个字符):");String str = getString();Tree[] array = new Tree[str.length()];for (int i = 0; i < array.length; i++) {// 建立单节点树数组Tree temp = new Tree();temp.root = new Node(str.charAt(i));array[i] = temp;}Tree lastTree = connectTree1(array, 0);lastTree.displayTree();}private static Tree connectTree1(Tree[] array, int index) {if (index * 2 + 1 > array.length - 1) { // 没有子树return array[index];} else if (index * 2 + 2 > array.length - 1) { // 有左子树Tree temp = array[index];temp.root.leftChild = connectTree1(array, index * 2 + 1).root;return temp;} else { // 有左右子树Tree temp = array[index];temp.root.leftChild = connectTree1(array, index * 2 + 1).root;temp.root.rightChild = connectTree1(array, index * 2 + 2).root;return temp;}}public static void main(String[] args) throws IOException {// 编程作业 8.1 - 8.3// code8_1();// code8_2();// code8_2_1();code8_3();}  // end main()// -------------------------------------------------------------public static String getString() throws IOException {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;}// -------------------------------------------------------------public static char getChar() throws IOException {String s = getString();return s.charAt(0);}// -------------------------------------------------------------public static int getInt() throws IOException {String s = getString();return Integer.parseInt(s);}// -------------------------------------------------------------}  // end class TreeApp// //////////////////////////////////////////////////////////////


 

package chap08;// postfix.java// parses postfix arithmetic expressions// to run this program: C>java PostfixAppimport java.io.*;              // for I/O////////////////////////////////////////////////////////////////class StackX {private int maxSize;private Tree[] stackArray;private int top;// --------------------------------------------------------------public StackX(int size)      // constructor{maxSize = size;stackArray = new Tree[maxSize];top = -1;}// --------------------------------------------------------------public void push(Tree j)     // put item on top of stack{stackArray[++top] = j;}// --------------------------------------------------------------public Tree pop()            // take item from top of stack{return stackArray[top--];}// --------------------------------------------------------------public Tree peek()           // peek at top of stack{return stackArray[top];}// --------------------------------------------------------------public boolean isEmpty()    // true if stack is empty{return (top == -1);}// --------------------------------------------------------------public boolean isFull()     // true if stack is full{return (top == maxSize - 1);}// --------------------------------------------------------------public int size()           // return size{return top + 1;}// --------------------------------------------------------------public Tree peekN(int n)     // peek at index n{return stackArray[n];}// --------------------------------------------------------------public void displayStack(String s) {System.out.print(s);System.out.print("Stack (bottom-->top): ");for (int j = 0; j < size(); j++) {System.out.print(peekN(j));System.out.print(' ');}System.out.println("");}// --------------------------------------------------------------}  // end class StackX// //////////////////////////////////////////////////////////////class ParsePost {private StackX theStack;private String input;// --------------------------------------------------------------public ParsePost(String s) {input = s;}// --------------------------------------------------------------// 编程作业 8.4public Tree doParse() {theStack = new StackX(20);             // make new stackchar ch;int j;Tree num1, num2, interAns;for (j = 0; j < input.length(); j++)       // for each char,{ch = input.charAt(j);              // read from inputtheStack.displayStack("" + ch + " ");  // *diagnostic*if (ch >= '0' && ch <= '9') {         // if it's a numberTree temp = new Tree();temp.root = new Node(ch);theStack.push(temp); // push it} else                               // it's an operator{num2 = theStack.pop();          // pop operandsnum1 = theStack.pop();Tree temp;switch (ch)                      // do arithmetic{case '+':temp = new Tree();temp.root = new Node('+');temp.root.leftChild = num1.root;temp.root.rightChild = num2.root;theStack.push(temp);break;case '-':temp = new Tree();temp.root = new Node('-');temp.root.leftChild = num1.root;temp.root.rightChild = num2.root;theStack.push(temp);break;case '*':temp = new Tree();temp.root = new Node('*');temp.root.leftChild = num1.root;temp.root.rightChild = num2.root;theStack.push(temp);break;case '/':temp = new Tree();temp.root = new Node('/');temp.root.leftChild = num1.root;temp.root.rightChild = num2.root;theStack.push(temp);break;default:// interAns = 0;}  // end switch// theStack.push(interAns); // push result}  // end else}  // end forinterAns = theStack.pop();            // get answerreturn interAns;}  // end doParse()}  // end class ParsePost// //////////////////////////////////////////////////////////////public class PostfixApp {public static void main(String[] args) throws IOException {String input;Tree output;System.out.print("Enter postfix: ");System.out.flush();input = getString();         // read a string from kbdif (input.equals(""))       // quit if [Enter]return;// make a parserParsePost aParser = new ParsePost(input);output = aParser.doParse();  // do the evaluation// System.out.println("Evaluates to " + output);output.displayTree();output.traverse(1);output.traverse(2);output.traverse(3);}  // end main()// --------------------------------------------------------------public static String getString() throws IOException {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;}// --------------------------------------------------------------}  // end class PostfixApp// //////////////////////////////////////////////////////////////


 

package chap08;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.PriorityQueue;import java.util.Queue;import java.util.Set;import java.util.TreeMap;// =============================================================================// 编程作业 8.5public class Huffman {public static Map<Character, String> map_char_code;public static Map<String, Character> map_code_char;static {map_char_code = new HashMap<Character, String>(); // 编码用代码表map_code_char = new HashMap<String, Character>(); // 解码用代码表}// 编码分为四步// 1.统计字符频率// 2.生成Huffman树// 3.生成编解码用代码表// 4.编码字符串public static String encode(String str) {char[] cchar = str.toCharArray();// 1.统计字符频率TreeMap<Character, Integer> map = new TreeMap<Character, Integer>();for (int i = 0; i < cchar.length; i++) {if (map.containsKey(cchar[i])) {map.put(cchar[i], map.get(cchar[i]).intValue() + 1);} else {map.put(cchar[i], 1);}}// 2.生成Huffman树// 先由所有字符生成单节点树的森林// 然后根据优先级合成单节点树为一棵树Queue<Tree> forest = new PriorityQueue<Tree>();Set<Map.Entry<Character, Integer>> set = map.entrySet();Iterator<Map.Entry<Character, Integer>> it = set.iterator();while (it.hasNext()) { // 生成单节点树Map.Entry<Character, Integer> en = it.next();Tree temp = new Tree();temp.root = new Node(en.getKey());temp.weight = en.getValue();forest.add(temp);}while (forest.size() > 1) { // 把单节点树合并为一棵树立Tree t1 = forest.remove();Tree t2 = forest.remove();Tree t3 = new Tree();t3.root = new Node();t3.weight = t1.weight + t2.weight;t3.root.leftChild = t1.root;t3.root.rightChild = t2.root;forest.add(t3);}Tree t = forest.remove(); // 最后一棵树// 3.生成编解码用mapString code = "";preOrder(t.root, code, map_char_code, map_code_char);// 4.编码字符串StringBuffer output = new StringBuffer();for (int i = 0; i < cchar.length; i++) {output.append(map_char_code.get(cchar[i]));}return output.toString();}// 遍历Huffman树生成编解码代码表private static void preOrder(Node localRoot, String code,Map<Character, String> map_char_code,Map<String, Character> map_code_char) {if (localRoot != null) {if (localRoot.cchar != '\0') {map_char_code.put(localRoot.cchar, code);map_code_char.put(code, localRoot.cchar);}preOrder(localRoot.leftChild, code + "0", map_char_code,map_code_char);preOrder(localRoot.rightChild, code + "1", map_char_code,map_code_char);}}// 解码// 根据确码代码表还原信息public static String decode(String str) {StringBuffer result = new StringBuffer();StringBuffer sb = new StringBuffer();for (int i = 0; i < str.length(); i++) {sb.append(str.charAt(i));if (map_code_char.get(sb.toString()) != null) {result.append(map_code_char.get(sb.toString()));sb = new StringBuffer();}}return result.toString();}public static void main(String[] args) {String code = encode("SUSIE SAYS IT IS EASY!");System.out.println(code);String str = decode(code);System.out.println(str);}// -------------------------------------------------------------public static String getString() throws IOException {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;}}// =============================================================================