4.基本的樹的知識。根不是內部結點。html
10.樹的全部葉子都位於同一層或者至少是彼此相差不超過一個層,就稱之爲是平衡。上圖的F,G,H,I,J位於同一層,與D只相差一層,因此上圖的樹是平衡的。下圖的樹由於O與D相差了兩層超過一層,因此這個樹是不平衡的。前端
11.滿樹:若是一棵n元樹的全部葉子都位於同一層且每一結點要麼是一片葉子要麼正好具備n個孩子,則稱此樹是滿的。如圖:java
14.計算策略:特別是二叉樹,一種策略是使用數組來存儲一棵樹。node
①前序遍歷:從根結點開始,訪問每一結點及其孩子。git
②中序遍歷:從根結點開始,訪問結點的左孩子,而後是該結點,再而後是任何剩餘結點。數組
③後序遍歷:從根結點開始,訪問結點的孩子,而後是該結點。數據結構
④層序遍歷:從根結點開始,訪問每一層的全部結點,一次一層。post
19.樹的操做及說明:學習
22.決策樹:結點表示決策點(也就是進行判斷的條件),左子結點表示「否」,右子結點表示「是」。this
問題1解決方案:按照左孩子的計算公式算就能夠,實際上它的位置至關於滿樹時所在的位置。
問題2解決方案:徹底樹從根結點到倒數第二層知足滿樹,最後一層能夠不徹底填充,其葉子結點都靠左對齊。滿樹必定是一棵徹底樹。以下圖:
public void preOrder(BinaryTreeNode<T> root) { if (root != null) { System.out.print(root.element + " "); preOrder(root.left); preOrder(root.right); } }
public void inOrder(BinaryTreeNode<T> root) { if (root != null) { inOrder(root.left); System.out.print(root.element + " "); inOrder(root.right); } }
public void postOrder(BinaryTreeNode<T> root) { if (root != null) { postOrder(root.left); postOrder(root.right); System.out.print(root.element + " "); } }
public void levekOrder() { if (root != null) { LinkedList<BinaryTreeNode> queue = new LinkedList<>(); BinaryTreeNode<T> p; queue.push(root); while (!queue.isEmpty()) { p = queue.removeFirst(); System.out.print(p.element + " "); if (p.left != null) queue.addLast(p.left); if (p.right != null) queue.addLast(p.right); } } else System.out.println("null"); }
問題4:表達式樹的計算過程是什麼?
表達式樹的求值是從下往上的,對本樹的分析過程,先是5-3=2,再是2*4=8,而後8+9=17
總結:①從下往上計算;②左右兩支分開計算;③四則運算前面的數都是左孩子,後面的數都是右孩子。
問題5解決方案:最深的葉結點的深度就是樹的深度;樹根的高度就是樹的高度。同結點的,深度數=高度數+1。
問題1:BinaryTreeNode類中此方法的代碼解讀。
問題1解決方案:此方法運用了遞歸原理,判斷左孩子是否存在,只要存在就+1,最後得出左孩子的總數用children變量存儲。以後再算右孩子的數量,一樣運用遞歸原理,判斷右孩子是否存在,存在就+1,最後與左孩子的總數加起來,成爲全部孩子(也就是沒有根結點)的數量。
問題2解決方案:整體思想有點相似於層序輸出,從根開始從右往左依次分層輸出。可是須要在輸出結點的同時,須要記錄本層每一個結點對應下一層的孩子數
public String printTree() { UnorderedListADT<BinaryTreeNode<ExpressionTreeOp>> nodes = new ArrayUnorderedList<BinaryTreeNode<ExpressionTreeOp>>(); UnorderedListADT<Integer> levelList = new ArrayUnorderedList<Integer>(); BinaryTreeNode<ExpressionTreeOp> current; String result = ""; int printDepth = this.getHeight(); int possibleNodes = (int)Math.pow(2, printDepth +1); int countNodes = 0; nodes.addToRear(root); Integer currentLevel = 0; Integer previousLevel = -1; levelList.addToRear(currentLevel); while (countNodes < possibleNodes) { countNodes = countNodes + 1; current = nodes.removeFirst(); currentLevel = levelList.removeFirst(); if (currentLevel > previousLevel) { result = result + "\n\n"; previousLevel = currentLevel; for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++) result = result + " "; } else { for (int i = 0; i < ((Math.pow(2, (printDepth - currentLevel + 1)) - 1)) ; i++) { result = result + " "; } } if (current != null) { result = result + (current.getElement()).toString(); nodes.addToRear(current.getLeft()); levelList.addToRear(currentLevel + 1); nodes.addToRear(current.getRight()); levelList.addToRear(currentLevel + 1); } else { nodes.addToRear(null); levelList.addToRear(currentLevel + 1); nodes.addToRear(null); levelList.addToRear(currentLevel + 1); result = result + " "; } } return result; }
getHeight()
是高度,因此能夠知道possibleNodes(最多結點數爲)2的^(printDepth+1)-1int printDepth = this.getHeight(); int possibleNodes = (int)Math.pow(2, printDepth +1);
nodes.addToRear(root); Integer currentLevel = 0 Integer previousLevel = -1; levelList.addToRear(currentLevel);
while (countNodes < possibleNodes) { countNodes = countNodes + 1; current = nodes.removeFirst(); currentLevel = levelList.removeFirst();
無上面代碼的效果圖:
result = result + "\n\n";
是由於二叉樹,爲了造成樹的形狀,因此至關於\n\n爲一組的存在,不會讓數在一行,同時保證了每行第一個數以前的空格數。其中for循環的循環體爲了保證每行第一個數以前的空格數。if (currentLevel > previousLevel) { result = result + "\n\n"; previousLevel = currentLevel; for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++) result = result + " "; }
無上面代碼的效果圖:
無上面代碼for循環的效果圖:
else { for (int i = 0; i < ((Math.pow(2, (printDepth - currentLevel + 1)) - 1)) ; i++) { result = result + " "; } }
無上面代碼的效果圖:
if (current != null) { result = result + (current.getElement()).toString(); nodes.addToRear(current.getLeft()); levelList.addToRear(currentLevel + 1); nodes.addToRear(current.getRight()); levelList.addToRear(currentLevel + 1); }
無上面代碼的效果圖:
else { nodes.addToRear(null); levelList.addToRear(currentLevel + 1); nodes.addToRear(null); levelList.addToRear(currentLevel + 1); result = result + " "; } }
無上面代碼的效果圖:
問題3:背部診斷器的相關文件是存在的,可是不能運行。
問題3解決方案:由於文件放錯位置了,默認是工程根目錄,和src是同一個級別的文件。不能放在src文件中,更不能放在src文件的子文件中。
問題4:DecisionTree類的代碼理解。
public DecisionTree(String filename) throws FileNotFoundException { File inputFile = new File(filename); Scanner scan = new Scanner(inputFile); int numberNodes = scan.nextInt(); scan.nextLine(); int root = 0, left, right; List<LinkedBinaryTree<String>> nodes = new java.util.ArrayList<LinkedBinaryTree<String>>(); for (int i = 0; i < numberNodes; i++) nodes.add(i,new LinkedBinaryTree<String>(scan.nextLine())); while (scan.hasNext()) { root = scan.nextInt(); left = scan.nextInt(); right = scan.nextInt(); scan.nextLine(); nodes.set(root, new LinkedBinaryTree<String>((nodes.get(root)).getRootElement(), nodes.get(left), nodes.get(right))); } tree = nodes.get(root); }
文件內容以下圖,第一個數13爲結點數。
下圖是從文件中讀出的信息所組成的樹。
List<LinkedBinaryTree<String>> nodes = new java.util.ArrayList<LinkedBinaryTree<String>>(); for (int i = 0; i < numberNodes; i++) nodes.add(i,new LinkedBinaryTree<String>(scan.nextLine()));
while (scan.hasNext()) { root = scan.nextInt(); left = scan.nextInt(); right = scan.nextInt(); scan.nextLine(); nodes.set(root, new LinkedBinaryTree<String>((nodes.get(root)).getRootElement(), nodes.get(left), nodes.get(right))); }
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一週 | 0/0 | 1/1 | 2/2 | |
第二週 | 1010/1010 | 1/2 | 10/12 | |
第三週 | 651/1661 | 1/3 | 13/25 | |
第四周 | 2205/3866 | 1/4 | 15/40 | |
第五週 | 967/4833 | 2/6 | 22/62 | |
第六週 | 1680/6513 | 1/7 | 34/96 |
計劃學習時間:20小時
實際學習時間:34小時
改進狀況:這周的新內容難度很大,學習時間遠超本身的計劃時間