《Java資料結構和演算法》第二版 Robert lafore 編程作業 第八章

來源:互聯網
上載者:User

《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;}}// =============================================================================

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.