本節課我們繼續二叉樹的話題。
這節課,先介紹一下二叉樹的幾個相關的性質,這些性質很簡單,但卻是我們進行資料結構的效能分析的基礎。
1. 在二叉樹的第 i 層上至多有
這個性質是顯然的,第一層有1個,第二層最多隻可能是第1層的兩倍,第三層是第二層的兩倍。
2. 深度為 k 的二叉樹,最多有
這條性質由 1 可以直接得出:將每一層的最大結點數相加。這是乙個公比為 2 的等比數列,其和為
再介紹乙個定義,如果乙個深度為 k 的二叉樹,正好有
滿二叉樹。如果乙個二叉樹,只有當第 k 層已經達到了
完全二叉樹。
例如,下圖就是一棵滿二叉樹:
而下面這個二叉樹就不是滿二叉樹,卻是乙個完全二叉樹:
3.具有 n 個結點的完全二叉樹的深度為
這個性質就是性質二的直接推論。不再多做解釋了。但這個性質向我們揭示了乙個問題:受二叉樹的樹形的影響,同樣有n個結點的乙個二叉樹,它的高度可能差別很大。比如,我們上節課的作業第二題,如果二叉搜尋樹是以(1, 2, 3, 4, 5, 6)或者(6, 5, 4, 3, 2, 1)的順序插入的話,二叉樹的高度就是6,退化為鍊錶。上節課的第一題,我們看到了,二叉樹中的搜尋效率與樹的高度成正比。二叉樹越矮,我們就能越快地找到目標,二叉樹越高,要經過的結點就會越多。
當樹形為完全二叉樹時,在樹中進行查詢的時間複雜度是 o(log n),而當樹形退化為鍊錶時,查詢的時間複雜度是 o(n),這個時間複雜度的差別是十分巨大的,大家可以算一下,如果有1000個結點,o(n)的時間複雜度,意味著1000次比較,而o(log n)的時間複雜度,只有10次比較,效能可以提公升100倍。好的資料結構和演算法設計的威力可見一斑。
另外,完全二叉樹的定義是很重要的,因為我們後面會學習一種威力十分強大的資料結構:堆,它就是乙個完全二叉樹。所以請記住完全二叉樹。
public void preorder(noden)
這裡,先介紹一下三種常用的遍歷方式:
1. 前序遍歷。先訪問根結點,再前序遍歷左子樹,最後前序遍歷右子樹。可見,這個操作的定義就是遞迴的。
2. 中序遍歷。先中序遍歷左子樹,再訪問根結點,最後中序遍歷右子樹。由於左子樹上的值都比根結點小,右子樹上的值都比根結點大,所以,中序遍歷一棵樹所得到的結果,是從小到大有序的,可以根據這個特點,來檢驗你的中序遍歷是否正確實現了。
3. 後序遍歷。先後序遍歷左子樹,再後序遍歷右子樹,最後訪問根結點。
public void midorder(node n)
在很多筆試題中,二叉樹的非遞迴遍歷是乙個很常見的考題。非遞迴遍歷有很多種實現方式,掌握起來要耗費很大的精力,而且還容易忘記。這一節將會介紹一種模擬遞迴函式的函式棧,從而實現非遞迴遍歷。
如果將未訪問完的結點入棧,每次只對棧頂元素進行操作,一旦棧頂元素被全部處理完,就將其出棧。繼續取棧頂元素進行處理,這就相當於回溯到了父結點。但是每次子結點全部訪問完回溯到父結點時,都需要知道父結點已經執行到哪一步了,在遞迴程式中,這個值是放在子結點所對應棧的 old eip 中的,因此,這是我們要模擬的乙個值。由於不需要像真正的遞迴程式那樣在回溯時恢復呼叫者的函式棧,所以 old ebp 和 old esp 這兩個值是不必模擬的。(要看懂這一節,一定要先把我前邊那篇關於遞迴的文章讀透)經過分析,我們可以給結點的定義加上乙個變數state來模擬old eip:
class node
}
為結點增加 state 變數,來標記當前結點已經訪問到哪一步。每次從子結點回溯回來的時候,都可以直接從當前結點裡取出,這樣就可以更加簡化這個程式。接下來,給出非遞迴的中序遍歷的**。
public void midorderwithoutrecurs()
else if (current.state == 1)
else if (current.state == 2)
else if (current.state == 3) }}
今天的課程就到這裡了。今天的作業:
1. 補全binarysearchtree的中序遍歷, 前序遍歷和後序遍歷的實現。
2. 補全非遞迴的前序遍歷的實現。
3. 樹的遍歷,還有一種辦法,那就是按層遍歷,例如,對於下面這棵樹
按層遍歷的結果,就是1, 2, 3, 4, 5, 6。請實現一下按層遍歷。
目錄:課程目錄
資料結構筆記(六) 二叉樹
樹 n n 0 個結點的有限集。n 0時稱為空樹。在任意一棵非空樹中 有且僅有乙個特定的稱為根的結點 當n 1時,其餘結點可分為m m 0 個互不相交的有限集t1 t2 tm,其中每乙個集合本身又是一棵樹,並且稱為根的子樹。相關概念 度 結點擁有的子樹數。層次 從根開始,根為第一層,根的孩子為第二層...
資料結構 樹形結構 二叉樹 樹
深度 高度 層數 滿二叉樹 深度k上不能再新增葉結點 完全二叉樹 深度k上,第k層只刪除右邊的葉結點 不完全二叉樹 深度k上,第k層刪除了左邊的葉結點 排序二叉樹 左根右的數值從小到大,且不重複 最優二叉樹 哈夫曼樹 結點的度不為1,帶權 一般右子樹帶權 的路徑長度最短。二叉樹的順序儲存 採用虛擬結...
資料結構 二叉樹練習 遞迴
以孩子兄弟鏈作為樹的儲存結構,編寫乙個求樹高度的遞迴演算法。遞迴模型 設f t 為樹t的高度 f t 0 若t null f t 1 若t沒有孩子節點 f t max f p 1 其他情況 p為t的孩子 int treeheight tsbnode t return max 1 二叉樹應用練習 假設...