含有m個元素的平衡n元樹具備的高度爲lognm。html
對於任何存儲在數組位置n處的元素而言,該元素的左結點將存儲在位置2n+1處,該元素的右結點將存儲在位置2(n+1)處。java
模擬連接策略容許連續分配數組位置而不用考慮該樹的徹底性。node
二叉樹--表達式樹表達式樹的及其內部結點包含着操做,且全部葉子也包含着操做數。對操做樹的求值是從下往上的。git
二叉樹--決策樹(背部疼痛診斷器)決策樹的結點表示決策點,其子結點表示在該決策點的可選項。決策樹的葉結點表示可能的判斷,這些推斷是根據決策結果得出的。算法
- 滿二叉樹是指除最後一層外,每一層上的全部結點都有兩個子結點。
- 若是一顆滿二叉樹的深度爲d,最大層數爲k
- 它的葉子數是: 2^d
- 第k層的節點數是: 2^(k-1)
- 總節點數是: 2^k-1 =>
(1 + 2 + 4 + 8 ··· + 2^(k-1)的和)
,其總節點數必定是奇數。
- 徹底二叉樹是指除最後一層外,每一層上的結點數均達到最大值;在最後一層上只缺乏右邊的若干結點。
- 徹底二叉樹的判斷方法:葉節點只能出如今最下層和次下層,而且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹
- 徹底二叉樹的特色是:
- 只容許最後一層有空缺結點且空缺在右邊,即葉子結點只能在層次最大的兩層上出現。
- 對任一結點,若是其右子樹的深度爲j,則其左子樹的深度必爲j或j+1。 即度爲1的點只有1個或0個。
(treeStack.peek()).printTree()
是把樹的形式從棧treeStack的頂部返回出來,再調用Expreesion類中的printTree方法(最噁心的部分),就成一棵樹了。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; }
Math.pow(2, printDepth + 1)
按照老師講的應該是2^printDepth - 1
,可是算法給出的是2^(printDepth+1)
,實際上咱們調用的getHeight()方法會從第零行開始計算,而在其實是從一層開始的,這樣的話就須要把再加1。而尾部的減1,沒有再此體現。在後面的while循環的條件來看,記錄輸出結點數量的變量 < possibleNodes,這樣的話就可使得記錄輸出結點數量的變量最大狀況等於possibleNodes - 1,這樣就是最大結點數。還有三個整形變量,一個是countNodes,是記錄輸出的結點數目的;一個是currentLevel記錄當前結點所在的層;一個是previousLevel記錄的是當前結點的前一層。過程:調出根結點A,此時對應的層數是-1,存放到對應的無序列表中。此時,countNodes(輸出的結點數目)的初始值爲0,
開始第一次進入循環,countNodes加1,調出無序列表中的結點。此時根結點的層數爲0,前一層爲-1,進入第一個條件,換行previousLevel等於currentLevel(兩個變量值都爲0),而後輸出根節點的內容,跳出第一個條件。進入第二個條件,將根結點的左子結點添加到無序列表的尾部,對應的記錄層數的無序列表添加數字1,再將根結點的右子結點添加到無序列表,對應記錄層數的無序列表添加數字1,第一次循環結束。
進行第二次循環,此時調出根結點的左子結點的內容和左子結點的層數,層數爲1,前一層是0,進入第一個條件,換行previousLevel等於currentLevel(兩個變量值都爲1),而後輸出左子結點的內容,跳出第一個條件。進入第二個條件,往裏面插入左結點的子結點,此時存放節點的無序列表內有和輸出的左結點同一層的右結點,和左結點的兩個子結點,先左節點後右結點,對應的層數應該均爲3,第二次循環結束。
進行第三次循環,此時調出的是根結點的右子結點和層數,層數和左結點相同也爲1,進入第一個條件(else部分),取消了換行和previousLevel等於currentLevel,這樣的話就和左子結點同行輸出,把根結點的兩個子結點都輸出來了。跳出第一個條件,再將右結點的兩個子結點和對應的層數放到無序列表,其中兩個子結點的層數均爲2,第三次循環結束。
進行第四次循環,此時調出的根結點的左結點的左子結點,此時對應的層數是2。此時的previousLevel爲1,currentLevel爲2,進入第一個條件的if部分,進行換行並輸出該結點的內容,跳出第一個條件,由於該結點爲空,因此進入第二個條件的else部分,會默認添加該結點的兩個子結點,可是子結點的內容爲空,即插入到無序列表的內容爲空,可是層數會進行增長,第四次循環結束。
重複進行上述循環(已經調用整個部分的相關代碼,股不在敘述操做),最後達到循環超過該樹的總結點數即possibleNodes跳出循環,輸出result就是整個樹了。express
問題3的解決方案:針對這個問題,剛開始只是敲上去而沒有真正去運行。後來聽同窗的運行以後有問題,這纔去運行,結果然有問題。不能轉化爲String,很神奇!!!明明在txt文件內已經有了內容的,就是轉換不成String。剛開始覺得是讀文件的部分有問題,可是沒找到問題,經過單步調試也只是在最後一步有問題。因此,很疑惑!更關鍵的是這個一樣的代碼在別的電腦上會有運行成功的。相同的一段代碼,個人電腦上會提醒有個判斷老是false,而別的上面就沒有。很迷...經過侯澤洋的幫助,是咱們在得到左結點或是右結點時候只是調出其中的內容,該節點的子結點根本沒有調出來致使的,徹底就是個只有該結點的一個樹了,在LinkedBinaryTree中添加幾句就能夠結點的子結點都調出來了。數組
- 始終有問題的部分:
- 錯誤圖片:
- 王文彬提供的代碼(修改位置):
- 侯澤洋提供的代碼(修改位置):
問題1的解決方案:return super.toString();
會出現帶有包名的哈希碼,沒有正常的輸出內容。準備從新書寫的輸出的代碼的時候,發現若是輸出的話就須要用遞歸的方法,來從樹中一層一層的從左往右的按順序輸出。可是若是用到了遞歸的話,註定用String類型的變量輸出不出來(由於要進行一個疊加的過程,而設置變量的話也不能在此方法下進行輸出。須要像以前的那個歸併排序和快速排序同樣,一個進行遞歸的主要方法,另外一個調用該遞歸方法,來達到代碼的實現。)圖過期用遞歸來實現的話,就能夠運用不一樣的遍歷方式。經過書上代碼--表達式樹的輸出樹狀形式,就直接搬過來實現toString方法(相關代碼分析在教材分析總結)。數據結構
- 產生帶包名哈希碼:
- 前序輸出:從根結點開始,訪問每個結點及其子結點。因此,先調出根結點的內容,而後從左結點開始調出至右結點的內容。
- 中序輸出:從根結點開始,先訪問結點的左子結點的內容,在調出該結點的內容,再訪問結點的右子結點的內容。
- 後序輸出:從根結點開始,先訪問該結點的子結點的內容,在退回到結點的內容。
- 層序輸出:從根節點開始,每一層的從左到右的進行輸出。
- 樹狀輸出(借鑑表達式樹的形式):
問題2解決方案:書上表達式樹的代碼在進行樹的輸出時候,總會輸出的稀亂稀亂的一堆,代碼也沒有爆紅。第一次經過單步調試發現,是本身的getHeight()方法的方法體沒有寫,致使輸出的結果老是0。還要本身修改getHeight()...悲慘自行補了相關代碼,先判斷樹是否是空的,不空的話經過PP10.3作的代碼,進行判斷是不是葉結點進行循環遍歷,在遍歷的過程當中進行計數。可是在輸出樹的狀況下就是缺最後一行,經過嘗試對一個已知高度的樹調用getHeight()方法時,在輸出的時候發現會比實際高度少1,因此在計數變量的初始值從0改成1嘗試一下,結果就完整了。學習
- 第一次修改:
- 第二次修改:
- 第三次修改:
無錯題,終於不用錯題總結了...this
本週結對學習狀況
20172314方藝雯
20172323王禹涵
結對學習內容:樹
第十章的樹學起來很費勁,徹底的一個接着一個,沒有順序,沒有結構的(二叉樹還好點)。課後的代碼相對簡單,可是書上的示例代碼寫的比課後代碼還麻煩。很是感謝侯澤洋的幫助,幫助我更好的理解樹的相關知識,有些代碼的問題是在幫助下完成的,這也顯示出個人不足,沒有更好的掌握知識,邏輯的相關內容只有本身弄懂才行,別人的幫助只是輔助的。起初還感受前面代碼相對簡單,但那是到了樹的部分真是欲哭無淚的感受。只能再好好的學習學習再學習了。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一週 | 0/0 | 1/1 | 15/15 | |
第二週 | 703/703 | 1/2 | 20/35 | |
第三週 | 762/1465 | 1/3 | 20/55 | |
第四周 | 2073/3538 | 1/4 | 40/95 | |
第五週 | 981/4519 | 2/6 | 40/135 | |
第六週 | 1088/5607 | 2/8 | 50/185 |