1.57k likes | 2.34k Views
第 六 章 樹狀結構 (Tree). 課程名稱: 資料結構 授課老師: _____________. 本章學習目標. 1. 讓讀者了解 樹狀結構 的相關名詞的 定義 。 2. 讓讀者了解 二元樹 的 建立 及 各種追蹤方式 。 3. 讓讀者了解 進階 的 各種樹狀結構 。 4. 介紹各種 高等樹 的 建立 、 加入 及 刪除 方法。. 本章內容. 6-1 樹狀結構 6-2 樹狀結構表示法 6-3 二元樹 (binary tree) 6-4 二元樹的追蹤 (Binary Tree Traversal)
E N D
第 六 章樹狀結構(Tree) 課程名稱:資料結構 授課老師:_____________
本章學習目標 1.讓讀者了解樹狀結構的相關名詞的定義。 2.讓讀者了解二元樹的建立及各種追蹤方式。 3.讓讀者了解進階的各種樹狀結構。 4.介紹各種高等樹的建立、加入及刪除方法。
本章內容 6-1 樹狀結構 6-2 樹狀結構表示法 6-3 二元樹(binary tree) 6-4 二元樹的追蹤(Binary Tree Traversal) 6-5 二元搜尋樹(Binary Search Tree) 6-6 堆積(累堆)樹 ( Heap Tree ) 6-7 高度平衡樹 ( AVL Tree )
本章內容 (補充單元) 6-8 引線二元樹(Threaded Binary Tree) 6-9 雙向堆積樹 ( DEAPS ) 6-10 B-tree 6-11 B+-tree 6-12 霍夫曼樹(Huffman Tree) 6-13 2-3樹 6-14 2-3-4 樹 6-15 紅-黑樹 ( Red-Black tree )
6-1 樹狀結構 【定義】 樹狀結構是由一個或多個節點組合而成的有限集合,它必須要滿足 以下兩點: 1. Tree(樹)不可以為空,至少有一個節點稱為Root(根節點)。 2. 其餘的節點分成T1 , T2,.....,Tn個互斥集合。因此,我們也可以稱T1 , T2,....., Tn為根節點的子樹 ( Sub tree ) 。 【圖解】
由於,樹狀結構和我們一般樹的形狀是差不多的,所以才稱為樹狀結構,以下我們就以圖形來做簡單的說明。如下圖所示。 Root(根節點) T3 T2 T1 圖6-1 樹狀結構
注意: 樹狀結構中不可以含有重邊、迴圈或不相連的情況。以下的例子為非樹狀結構。
【樹狀結構的專有術語介紹】 在認識樹狀結構之前,您必須了解相關的專有術語。我們先以下圖的樹狀結構來為您說明: 樹根(root):每一棵樹的最上層的節點,稱為樹根,而A就是為這棵樹 的樹根。節點(node):樹的節點代表著某項資料,A、B…、L都是節點。 A樹根
【樹狀結構的專有術語介紹】(續) 子樹(subtree):把A去掉之後,就剩下以B、C及D為樹根的三棵子樹。樹林(forest):是由N≧0個互斥子樹的集合。把樹根A去掉之後,剩下 的部分就叫樹林。階度(level):表示節點的階層位置。樹根A的階度是1,B的階度是2, K的階度是4。
【樹狀結構的專有術語介紹】(續) 高度(height):一棵樹中節點的最大階度就是高度, 而此樹的高度為4。父節點(parent):每一個節點的上一個節點就是父節點,B節點的父節 點就是A。 子節點(children):每一個節點的下一個節點就是子節點,D節點的子 節點就是 H、I及J。
【樹狀結構的專有術語介紹】(續) 分支度(degree):一個節點的子樹之個數稱為該節點的分支度。 例如:A節點的子樹之個數為3,所以,分支度為3。 B節點的子樹之個數為2,所以,分支度是2。終點節點(terminal node):分支度為0的節點,這棵樹的終點節點 (又稱樹葉節點)共有K、F、G、H、I、L。
6-2 樹狀結構表示法 【方法一】直接利用Link List表示 【作法】假設樹有n個節點, 樹的分支度為k,則節點結構如下: 其中:Data:存入節點的資料值 Link i:指向子節點的指標
【實例】假設有以下一棵三個階度的樹狀結構,請利用Link list 來表示,並說明此方法的缺點。 【分析】 節點數n=6(∵A~F) 分支度k=3(∵A的分支度為3) 【解答】 【缺點】極度浪費Link空間。 【解析】 (1)總共的Link空間為:n×k=6×3=18 (2)有用的Link空間為:n-1=6-1=5 ∴浪費的Link數為:n×k-(n-1)=18-5=13
【樹轉換成二元樹的理由】 假設樹有n個節點, 樹的分支度為k,鏈結的浪費比例為: 【浪費比率】 (1)k=2時2元樹的鏈結浪費比率約為1/2 (2)k=3時3元樹的鏈結浪費比率約為2/3 (3)k=4時4元樹的鏈結浪費比率約為3/4 當k=2時,它的鏈結浪費比率最低,所以為了改進記空間浪費的缺點,我們將樹化成二元樹(Binary tree)的結構。 【方法二】將樹化成二元樹後再儲存在下一單元會詳細介紹。 浪費的Link數 總共的Link空間
6-3 二元樹(Binary tree) 【定義】二元樹可以為空,若不為空,則具有以下兩個特性: 1.具有根節點(Root)及左子樹和右子樹。 2.左、右子樹亦是二元樹(亦即分支度小於或等於2)。 簡單的說,二元樹最多只能有兩個子節點,就是分支度小於或等於2。 根節點(Root) 左子樹 右子樹
【特性】 1、在二元樹的第 i 階度(Level)上最多的節點個數為 2 i-1 , i >= 1 。 【解析】
2、在高度為 h 的二元樹中最多的節點個數為 2 h -1 , h >= 1 。 【解析】
3. 若一棵二元樹 T 的總節點數(Node)為 V,總邊(Edge)數為 E,則V=E+1 【解析】 假設:V:總節點數(如下圖中的1~15個節點) E:總邊數(如下圖中的14條邊)
4. 一棵二元樹,若 n0為樹葉節點的數量,n2為分支度為 2 的節點 數量,則n0 = n2 + 1 【證明】 假設: n:總節點數 n0:分支度為0的節點數(樹葉節點) n1:分支度為1的節點數 n2:分支度為2的節點數 E:總邊數 已知: n=n0 +n1 +n2 n=E+1 ------ E=n1 +2n2 所以: n0 +n1 +n2=n1 +2n2+1 n0= n2+1 n2=6 n1=1 n0=7
【實例1】假設有8個Leafs (樹葉節點) ,則Degree(分支度)為2的 節點數為多少? 【解答】已知:n0 = 8,求n2 =? 代入公式:n0 = n2+ 1 n0=8代入上式,n2=7 【圖解驗證】 n2=7 n0=8 因此,只要先得知樹葉節點總數,就可以推算出分支度為2的節點數了!
【實例2】假設有7個Degree為2的Nodes,則Leaf個數為多少?【實例2】假設有7個Degree為2的Nodes,則Leaf個數為多少? 【解答】已知:n2 =7,求n0 = ? 代入公式:n0 = n2+ 1 n2=7代入上式,n0=8 【圖解驗證】 n2=7 n0=8 因此,只要先得知分支度為2的節點數,就可以推算出樹葉節點總數了!
【n個節點可組成多少不同的二元樹】 唸成C n取r 公式: 其中 ,也可以記作C(n,r)或 (1)當n=1 時, 種 (2)當n=2時,種 (3)當n=3時,種
6-3.1 斜曲二元樹 ( Skewed binary tree ) 【定義】 當一個二元樹完全沒有右節點或左節點時,我們就把它稱為左斜曲樹或右斜曲樹。它可分為二種: 1.左斜曲(Left-skewed)二元樹 2.右斜曲(Right-skewed)二元樹
1.左斜曲(Left-skewed)二元樹 【定義】表示二元樹,只有左兒子,無右兒子。 如下圖所示。 左兒子
2.右斜曲(Right-skewed)二元樹 【定義】表示二元樹,只有右兒子,無左兒子。 如下圖所示。 右兒子
6-3.2 嚴格二元樹 (Strictly binary tree) 【定義】若二元樹的每個非終端節點(1,2,4),均為非空的左右子樹。 如下圖所示。
6-3.3 完滿二元樹 ( Full Binary Tree ) 【定義】一個高度為 h 的完滿二元樹 ( Full Binary Tree ),當h >= 0時, 則它會具有 2h -1 個節點。 【題目】假設有一棵完滿二元樹,其高度h=4時,請問此棵二元樹會 具有多少個節點? 【解答】已知h=4 節點數= 2h -1= 24 -1=15 高度h=4 節點數=15
6-3.4 完整二元樹(Complete Binary Tree ) 【定義】一個二元樹有 n 個節點且高度為 h ,若且唯若,滿足: 1. 節點數n一定會介於:2 h-1 -1 < n < 2 h -1 2. 節點編號和高度h必須要與完滿二元樹之前n個節點編號一致。 【目題1】假設有一棵二元樹,共有 14 個節點(即n=14)且高度為4, 現在想要建立成一棵完整二元樹,請問如何建立呢? 【解答】 前14個節點編號一致 完滿二元樹 完整二元樹
6-3.4 完整二元樹(續) 【題目2】假設有一棵完整二元樹,其高度h=4時,請問此棵二元樹的 節點數最少與最多各多少? 【解答】已知h=4 節點數n一定會介於:2h-1 -1 <n<2h -1=23-1<n<24-1=7<n<15 ∴n最少節點數=8 ∴n最多節點數=14 高度h=4 完整二元樹
【分析】 由定義我們可以得知: 完整二元樹並不一定是完滿二元樹;但是, 完滿二元樹則必定是完整二元樹。 由上面介紹的「嚴格二元樹」、「完滿二元樹」及「完整二元樹」三種定義,我們可以歸納其之間的關係如下所示: 「完滿二元樹」≧「完整二元樹」≧「嚴格二元樹」
【基本性質】 假設一個具有n 個節點的完整二元樹以循序的方式編號,並依序存放在陣列A中,即第 i 個節點存放在 A 中,1in,因此,就會有以下幾個性質: (1)根節點位於 A[1] A[1] A[2] A[3] A[4] A[5] A[6] A[7]
【基本性質】(續) (2)節點 i的父節點位在A ,i1 【舉例】假設要尋找節點E的父節點儲存位置 【解答】 【圖解驗證】節點E的父節點儲存位置為2 5/2取下限=2 i代入5 A[1] A[2] A[3] A[4] A[5] A[6] A[7] 父節點 節點E
【基本性質】(續) (3)若2in,則節點i的左兒子位在A ,若2i>n,則節點i沒有左兒子 【舉例1】假設要尋找節點C的「左兒子」儲存位置 【解答】由於節點C在位置i=3,並且2i≦n,亦即2*3≦6,所以有左兒子 【圖解驗證】節點C的「左兒子」儲存位置為6 2*3取下限=6 i代入3 A[1] A[2] A[3] A[4] A[5] A[6] A[7] 節點C 左兒子
【基本性質】(續) (3)若2in,則節點i的左兒子位在A ,若2i>n,則節點i沒有左兒子 【舉例2】假設要尋找節點D的「左兒子」儲存位置 【解答】由於節點D在位置i=4,並且2i>n,亦即2*4>6,所以沒有左兒子 【圖解驗證】節點D的「左兒子」儲存位置為8 2*4取下限=8(找不到(沒有左兒子)) i代入4 A[1] A[2] A[3] A[4] A[5] A[6] A[7] 節點D 沒有左兒子
【基本性質】(續) (4)若2i+1n,則節點i的右兒子位在A ,若2i+1>n, 則節點i 沒有右兒子 【舉例1】假設要尋找節點B的「右兒子」儲存位置 【解答】由於節點B在位置i=2,並且2i+1≦n,亦即2*2+1 ≦ 6,所以有右兒子 【圖解驗證】節點B的「右兒子」儲存位置為5 2*2+1取下限=5 i代入2 A[1] A[2] A[3] A[4] A[5] A[6] A[7] 節點B 右兒子
【基本性質】(續) (4)若2i+1n,則節點i的右兒子位在A ,若2i+1>n, 則節點i沒有右兒子 【舉例2】假設要尋找節點C的「右兒子」儲存位置 【解答】由於節點C在位置i=3,並且2i+1>n,亦即2*3+1>6,所以沒有右兒子 【圖解驗證】節點C的「右兒子」儲存位置為7 2*3+1取下限=7 找不到(沒有左兒子) i代入3 A[1] A[2] A[3] A[4] A[5] A[6] A[7] 節點C 沒有右兒子
6-3.5 二元樹表示法 一般而言,二元樹的表示法有兩種: 1.以陣列(Array)表示 2.以鍵結串列(Linked List)表示
一、以陣列(Array)表示 【定義】首先將二元樹想像成一個「完滿二元樹」,並使用「一維陣列」 建立二元樹的表示方法及索引值的配置。 【作法】假設二元樹(Binary Tree)之高度為h,則準備一維陣列 A[1…2h-1],依照「節點編號」依序存入陣列中。
【舉例】假設有一棵二元樹,如下圖所示: 請利用陣列(Array)來表示。 【解答】 步驟一:想像成一個「完滿二元樹」,並加上節點編號 步驟二:因為高度h=3 ∴準備一個一維陣列A[1…2h-1]的空間, 亦即A[1…7]如下所示: A[1] A[2] A[3] A[4] A[5] A[6] A[7]
步驟三:依照「節點編號」順序存到一維陣列中步驟三:依照「節點編號」順序存到一維陣列中 A[1] A[2] A[3] A[4] A[5] A[6] A[7]
【優點】 1. 容易取得父節點、左兒子及右兒子。 【解析】 節點 i 的父節點位在 A ,i1 若 2in,則節點 i 的左兒子位在 A 若 2i+1n,則節點i的右兒子位在 A 2.對於「完滿二元樹」之儲存完全沒有空間的浪費。 【解析】 A[1] A[2] A[3] A[4] A[5] A[6] A[7]
【缺點】 1.節點之插入與刪除較困難。 【解析】插入較困難:往後挪移位置 刪除較困難:往前挪移位置
【缺點】 2.對於斜曲二元樹(Skewed B.T.)的儲存極度浪費空間。 【解析】 假設有一個斜曲二元樹高度為h 其準備2h-1空間 實際有用空間為h 浪費的空間為(2h-1)-h 高度為h=3 準備23-1=7空間 A[1] A[2] A[3] A[4] A[5] A[6] A[7]
二、以鏈結串列(Link List)表示 【定義】使用動態記憶體配置來建立二元樹,利用兩個指向左和右子樹 的指標。 【節點結構】 (1)Lchild與 RChild:指標指向左右子樹 (2)Data:存Node之資料值
【舉例】假設有一棵二元樹,如下圖所示: 請利用鏈結串列(Link List)來表示。 【解答】 A為資料值 指向左子樹 指向左子樹 若沒有右子樹 則指標指向空節點(null) 若為終端節點,則左、右指標指向空節點(null)
【優點】 1.節點之Insert / Delete 容易。(∵只要更改指標即可) 2.鏈結串列(Link List)對於斜曲二元樹儲存較陣例(Array)來表示法 節省空間。 【圖解】 高度為h=4 (1)利用陣例(Array)來表示 (2)利用鏈結串列(Link List)來表示 浪費空間數:15-4=11 浪費空間數:4*2-3=5
【缺點】 1.不易找到父節點。 2.Link空間約浪費一半。如下圖中,當n=4時,浪費5個空間。 【解析】 二元樹有n個節點總共Link空間為2n 例如:下圖中n=4,則總共Link空間為=2*4=8 有用的Links空間為n-1。如上圖中n=4,則使用的Links空間為=3 無用(空)Links空間為2n-(n-1)=n+1 。如上圖中, 無用的Links 空間為=2*4-(4-1)=4+1=5
6-3.6 一般樹化為二元樹 在樹狀結構中,二元樹在處理時,是比較節省記憶體空間的。 【解析】 因此,我們可以將一般樹轉換成二元樹,其方法如下: 步驟一:將樹的各階層兄弟節點利用平行線連接起來。 步驟二:刪掉所有右邊父子節點間的連結,只留最左邊的父子節點。 步驟三:右邊的兄弟節點順時鐘轉45度。 二元樹 一般樹
【實例】請將下面的一般樹化為二元樹 【解答】 步驟一:將樹的各階層兄弟節點利用平行線連接起來。