1 / 52

第 6 章 樹狀結構

第 6 章 樹狀結構. 目次. 6.1 樹狀結構的專有名詞 6.2 二元樹 6.3 二元樹的表示方法 6.4 二元樹追蹤 6.5 引線二元樹 6.6 二元搜尋樹 6.7 堆積 6.8 集合的表示法 6.9 其它論題. A. C. D. B. H. G. I. E. F. M. N. J. K. L. 6.1 樹狀結構的專有名詞. 樹的表示法. 階度 1 2 3 4. 6.1 樹狀結構的專有名詞 (con.t). 樹狀結構的專有名詞 節點 (node) 與邊 (edge)

swann
Télécharger la présentation

第 6 章 樹狀結構

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第 6 章 樹狀結構

  2. 目次 6.1 樹狀結構的專有名詞 6.2 二元樹 6.3 二元樹的表示方法 6.4 二元樹追蹤 6.5 引線二元樹 6.6 二元搜尋樹 6.7 堆積 6.8 集合的表示法 6.9 其它論題

  3. A C D B H G I E F M N J K L 6.1 樹狀結構的專有名詞 • 樹的表示法 階度 1 2 3 4

  4. 6.1 樹狀結構的專有名詞 (con.t) • 樹狀結構的專有名詞 • 節點(node)與邊(edge) • 祖先(ancestor)節點與子孫(descendant)節點 • 父節點(parent node)與子節點(children node) • 兄弟節點(sibling node) • 非終點節點 • 終點節點(terminal node)或樹葉節點(leaf node)

  5. 6.1 樹狀結構的專有名詞 (con.t) • 樹狀結構的專有名詞 • 分支度(degree) • 階度(level) • 高度(height) • 深度(depth) • 樹林(forest)

  6. 6.2 二元樹 • 為何使用二元樹? • 為了減少儲存空間的浪費 • 二元樹 • 二元樹是由節點所組成的有限集合,這個集合若不是空集合;就是由樹根、右子樹(right subtree)及左子樹(left subtree)所組合而成。 • 其中右子樹和左子樹可以是空集合。 A A B B

  7. 6.2 二元樹 (con.t) • 二元樹與一般樹的不同處 • 二元樹的節點個數可以為零 • 二元樹的節點有排列順序的關係 • 二元樹中每一節點的分支度至多為 2 • 二元樹的種類 • 左/右斜樹(left/right skewed tree):圖(a) • 滿枝二元樹(fully binary tree) :圖(b) • 完整二元樹(complete binary tree) :圖(c)

  8. 1 A A B 2 3 B C 4 5 D E 7 C G 6 F H 9 15 D 8 I 14 12 11 10 K J 13 (a) (b) (c) 6.2 二元樹 (con.t)

  9. 6.2 二元樹 (con.t) • 二元樹的特徵 • 二元樹在第 i 階度的最多節點數為 2i-1,i≧1 • 階度(或深度)為k的二元樹,最多的節點數為2k-1,k≧1 • 二元樹,若n0表示所有的樹葉節點,n2表示所有分支度為 2 的節點,則n0=n2+1 • Ex:圖6.3

  10. 6.3 二元樹的表示方法 • 如何將二元樹的節點儲存在一維陣列? • 下圖為圖(c)儲存在一維陣列的表示法 • 若運用在非完整二元樹或滿枝二元樹時,可能會造成許多空間的浪費 → 使用鏈結串列

  11. LLINK DATA RLINK 6.3 二元樹的表示方法(con.t) • 鏈結串列方式 • 每個節點包含三個欄位: 左鏈結(left link)、資料(data)、右鏈結(right link) • 二元樹的資料結構

  12. 6.4 二元樹追蹤 • 二元樹的追蹤(traversal) • 中序追蹤(inorder):左子樹 → 樹根 → 右子樹 • 前序追蹤(preorder):樹根 → 左子樹 → 右子樹 • 後序追蹤(postorder):左子樹 → 右子樹 → 樹根

  13. 6.4 二元樹追蹤(con.t) • 中序追蹤(inorder):左子樹 → 樹根 → 右子樹 void inorder(Node type *tree) { if (tree != NULL){ inorder(tree->llink); printf("%d", tree->data); inorder(tree->rlink); } }

  14. 6.4 二元樹追蹤(con.t) • 前序追蹤(preorder):樹根→左子樹→ 右子樹 void preorder(Node type *tree) { if (tree != NULL){ printf("%d", tree->data); preorder(tree->llink); preorder(tree->rlink); } }

  15. 6.4 二元樹追蹤(con.t) • 後序追蹤(postorder):左子樹→右子樹→樹根 void postorder(Node type *tree) { if (tree != NULL){ postorder(tree->llink); postorder(tree->rlink); printf("%d", tree->data); } }

  16. 6.5 引線二元樹 • 為何使用引線二元樹? • 為了便利儲存及節省LINK欄位的浪費,而有二元樹的產生。但二元樹中仍然會造成n+1個LINK欄位的浪費(n為節點數目),因此將空的LINK欄位換成引線(thread)的指標。 • 引線二元樹 • 二元樹中的LINK欄位以引線的指標取代,而引線是指到二元樹的其它節點 • 引線二元樹的有一個「開頭節點(head node) 」,並且不存放任何資料。

  17. 相對引線二元樹 A A B C C B D G E F D G E F H I H K J I K J 6.5 引線二元樹(con.t) • 二元樹 → 引線二元樹 • 先將二元樹的資料以中序追蹤方式排列 • 再將缺少左或右LINK的節點排出 • 最後將上述節點的左或右LINK指標指向其相鄰的左、右節點

  18. LBIT LLINK DATA RLINK RBIT 6.5 引線二元樹(con.t) • 引線二元樹的資料結構 • LBIT = 1,LLINK是正常指標 • LBIT = 0,LLINK是引線 • RBIT = 1,RLINK是正常指標 • RBIT = 0,RLINK是引線

  19. 6.5.1 引線二元樹的優點 • 追蹤任一節點的中序後繼者(inorder successor) Node_type *insucc(Node_type *ptr) { Node_type *this_n; this_n = ptr->rlink; if (ptr->rbit == 1) while (this_n->lbit == 1) this_n = this_n->llink; return this_n; }

  20. 6.5.1 引線二元樹的優點(con.t) • 追蹤引線二元樹 void tinorder(Node_type *tree, Node_type *head) { tree = head; printf(“%d, tree->data”); for(;;){ tree = insuc(tree); if(tree == head) return; printf(“%d”,tree->data); } }

  21. 6.5.1 引線二元樹的優點(con.t) • 追蹤引線二元樹的中序前行者(inorder predecessor) Node_type *pred(Node_type *ptr) { Node_type *this_n; this_n = ptr->llink; if(ptr->lbit == 1) while(this_n->rbit == 1) this_n = this_n->rlink; return this_n; }

  22. 1 S 2 3 T 5 4 6.5.2 引線二元樹的加入 • 加入新節點於某節點的右方 void insert_right(Node_type *node_parent, Node_type *node) { Node_type *w; node->rchild = node_parent->rchild; node->rbit = node_parent->rbit; node->lchild = node_parent; node->lbit = 0; node_parent->rchild = node; node_parent->rbit = 1; if ( node->rbit == 1 ){ /*node底下還有tree*/ w = insucc( node ); w->lchild = node; } } 加T節點於S節點之右方

  23. 1 S 2 3 T 5 4 6.5.2 引線二元樹的加入(con.t) • 加入新節點於某節點的左方 void insert_left(Node_type *node_parent, Node_type *node) { Node_type *w; node->lchild = node_parent->lchild; node->lbit = node_parent->lbit; node->rchild = node_parent; node->rbit = 0; node_parent->lchild = node; node_parent->lbit = 1; if ( node->lbit == 1 ){ /*node 底下還有tree*/ w = inpred( node ); w->rchild = node; } } 加T節點於S節點之左方

  24. prev this 1 2 3 4 6.5.3 引線二元樹的刪除 • 假設有一棵引線二元樹如下所示:

  25. 1 prev 2 this 3 4 6.5.3 引線二元樹的刪除(con.t) • 刪除樹葉節點,且是某父節點的左方 • 如右圖 • 刪除的過程 prev→1child = this→1child; prev→1bit = 0 • 刪除後的情況與之前的結果相同

  26. 1 2 3 6.5.3 引線二元樹的刪除(con.t) • 刪除樹葉節點,且是某父節點的右方 • 如圖上的節點 4 • 刪除的過程 prev→1child = this→1child; prev→1bit = 0 • 刪除後的情況

  27. 6.6 二元搜尋樹 • 何謂二元搜尋樹(binary search tree)? • 二元搜尋樹可以是空集合;假使不是空集合,則樹中的每一節點均含有一鍵值(key value) • 具有下列特性: • 在左子樹的所有鍵值均小於樹的鍵值 • 在右子樹的所有鍵值均大於樹的鍵值 • 左子樹和右子樹亦是二元搜尋樹 • 每個鍵值都不一樣

  28. 50 40 65 30 45 60 6.6.1 二元搜尋樹的加入 • 基於二元搜尋樹的特性,因此要加入某一鍵值時只要逐一比較,並依據鍵值的大小往右或往左 ,便可找到此鍵值欲加入的適當位置。 • Ex:假設有棵二元搜尋樹如下:

  29. 50 40 65 30 45 60 48 6.6.1 二元搜尋樹的加入(con.t) • 加入鍵值 48

  30. 50 40 65 30 45 90 60 48 6.6.1 二元搜尋樹的加入(con.t) • 加入鍵值 90

  31. 45 40 65 30 60 60 40 65 30 45 6.6.2 二元搜尋樹的刪除 • 樹葉節點的刪除 • 直接刪除 • 非樹葉節點的刪除 • 在左子樹找一最大節點或在右子樹找一最小節點來取代將被刪除的節點(Ex:刪除 50) 取右子樹最小的節點 取左子樹最大的節點

  32. 30 25 22 18 19 10 13 11 15 14 6.7 堆積 • 何謂堆積(Heap)? • 堆積是一棵二元樹,其樹根的鍵值大於子樹的鍵值, • 必須符合完整二元樹的定義 • 不管左子樹和右子樹的大小順序(與二元搜尋樹最大的差異處)

  33. 6.7 堆積(con.t) • 堆積可以用於排序上,簡稱 Heap Sort。 • 堆積排序的步驟: • 先將資料利用完整二元樹的方式將其建立起來 • 將建立完成的完整二元樹「調整」成 Heap • 以堆疊(由大到小)或佇列(由小到大)的方式輸出

  34.  換 換 1 1 1 30 15 23 3 2 3 2 3 2 15 23 23 15 30 30 6.7 堆積(con.t) • 堆積的調整方式 • 由上而下,從樹根開始分別與其子節點相比,若前者大則不用交換,反之,則要交換;以符合父節點大於子節點

  35.  15 30 23 23 30 15 6.7 堆積(con.t) • 由下而上,先算此棵樹的節點數目,假設 n,再取其 n/2,從此節點 n/2,開始與它的最大子節點相比,若子節點的鍵值大於父節點之鍵值,則相互對調,一直做到樹根止 • 子節點先比,找出大者與其父節點比(如下圖)

  36. 40 40 40 23 23 10 10 23 30 40 15 8 15 30 8 30 15 8 10 23 30 15 10 8 50 6.7.1 堆積的加入 • 堆積的加入 • 先按照建立一棵完整二元樹的特性將資料加入 • 判斷加入後的二元樹是否為一棵堆積樹,若符合則完成加入;若否,則再加以調整之。 • Ex:6-47

  37. 40 40 40 23 23 10 10 23 30 40 15 8 15 30 8 30 15 8 10 23 30 15 10 8 50 6.7.1 堆積的加入(con.t) • Ex:下圖中雙圓圈表示剛加入的節點   再加入50 (加入後不是一棵Heap,所以要調整) 

  38. 40 40 50 換 23 23 50 30 23 40 換 15 15 10 8 10 8 30 50 15 10 8 30 6.7.1 堆積的加入(con.t) • 調整過程  

  39. 40 40 40 刪除30 調整 10 30 20 20 15 20 15 15 10 10 6.7.2 堆積的刪除 • 堆積的刪除 • 將完整二元樹的最後一節點取代被刪除的節點 • 判斷刪除後的二元樹是否為一棵堆積樹,若符合則完成刪除;若否,則再加以調整之 • Ex:

  40. 20 10 換 換 15 10 15 20 6.7.2 堆積的刪除(con.t) • 再刪除 40,則將10取代之

  41. 10 21 28 32 29 6.7.3 Min-Heap • Heap的種類 • Max-heap、Min-Heap、Min-Max-Heap、deap • 上述提到的堆積是屬於Max-Heap,一律是上大於下,父節點的鍵值一律大小其子節點 • 何謂Min-Heap? • 父節點的鍵值一律小於子節點 • 加入與刪除的方式與Max-Heap類似 • Ex:如右圖

  42. 8 3 4 10 9 6 2 1 7 5 6.8 集合的表示法 • 利用樹的方式來表示集合(Set) • 有資料1到10,共十個元素。若將這些元素分為三個集合,S1={1, 3, 5, 7}、 S2={2, 4, 6}、 S3={8, 9,10};因為S1、S2 、S3三集合中沒有相同的元素,因此稱這三個集合為互斥集合(disjoint set) • 如何將S1、S2 、S3以樹的型態表示呢? S1 S2 S3

  43. 6.8.1 互斥集合資料的表示法 • 以陣列來儲存資料 • 如下圖 • 其中 i 為元素值,而p(i)為 i 的 parent 值(若p(i)為-1時,代表沒有parent)

  44. A A A 利用第(3)步驟 …  利用第(1)及第(2)步驟 …  C B D B C D B C D 6.9 其它論題 • 如何將樹和樹林(forest)轉換為二元樹的方式? • 樹轉換為二元樹 (1) 將節點的所有兄弟節點連接在一起 (2) 把所有不是連到最左子節點的子節點鏈結刪除 (3) 順時針旋轉 45度 • Ex:

  45. H A E C D B G I F 6.9 其它論題(con.t) • 樹林轉換為二元樹 (1) 先將樹林中的每棵化為二元樹(不旋轉45度) (2) 把所有二元樹利用樹根節點全部鏈結在一起 (3) 旋轉45度 • Ex:(1) 利用第(1)步驟 : 

  46. H A E C D B G F I E A H C B F G D I 6.9 其它論題(con.t) • (2) • (3) 利用第(2)步驟 :  利用第(3)步驟 : 

  47. A E B F H C I G D 6.9 其它論題(con.t) • 轉換完成

  48. 6.9.2 決定唯一的二元樹 • 如何決定唯一的二元樹? • 給予一對中序與前序,或中序與後序的次序就可決定一棵二元樹 • Ex:給定的中序為 FDHGIBEAC 給定的前序為 ABDFGHIEC

  49. A C FDHGIBE 6.9.2 決定唯一的二元樹(con.t) • 決定過程 • 由前序次序知道A是樹根 • 且由中序次序知道C是A的右子點

  50. A C B E FDHGI 6.9.2 決定唯一的二元樹(con.t) • 由前序知道B是FDHGIE的父節點,並從中序次序知道E是B的右子節點

More Related