第6 章 - 周清江副教授

Download Report

Transcript 第6 章 - 周清江副教授

Ch06 樹狀結構
淡江大學 周清江
1
6.1 樹狀結構基本概念
2
樹的範例:電腦系統架構圖
3
請再想想有那些應用範例?
樹的組成元件
4
樹狀結構不允許出現的情況
節點間存在遞
迴關係
子樹和樹根節點沒
有連結
5
樹的基本術語和表示法
樹(Tree)
A
樹根節點(Root)
子樹(Subtree)
B
C
分支度(Degree)
樹葉節點 (Leaf)
G
D
E
F
終端節點(Terminal Nodes)
I
J
K
非終端節點(Nonterminal Nodes)
子節點(Children)
兄弟(Siblings)節點:不一定先有兄才有弟,依需要而定
父節點(Parent)
祖先節點(Ancestor)
階度(Level)、高度(Height)、深度(Depth)
樹林(Forest)













6
階度
1
2
H
3
L
4
6.2 樹狀結構表示法
串列表示法


設計節點

先檢測最大分支度
左子右弟表示法 (6.2.2)

7
6.2.1串列表示法

以字串表示樹狀結構


加上括弧來區別
以圖 6.4 為例



A(B(D(H))(E)) (C(F(I(K))(J))(G))
OR A( B( D(H)( ) )(E) ) (C (F ( I(K)( ) )(J) )(G) )
太複雜,不需要記
8
課本圖 p.6-7 為要求子
樹必須由左至右一一填
入時的樹狀結構表示法
這是一般對左右子樹不加限
制的樹狀結構表示法
6.2.1串列表示法
用來表示樹的節點:
鏈結至
子樹1
節點資料
鏈結至
子樹2
A
鏈結代表 父子
關係
0
B
D
I 0 0 0
0
鏈結至
子樹N
‧‧‧
C
E 0 0 0
J 0 0 0
F 0 0 0
G
0 0
0
H
K 0 0 0
第 6 頁投影片的樹狀結構之串列表示
9
0 0
L 0 0 0
6.2.2 左子右弟表示法
先將一般的樹以 2 元樹來表示
6.3 會詳細說明 2 元樹,6.4 會說明 2 元樹之表示法
轉換步驟



1.
2.
3.
為每個非樹葉節點保留到最左子樹的鏈結,其餘鏈結一律
刪除
每個節點與其右邊的兄弟節點鏈結起來
將樹旋轉 45o
再用 6.2.1 的串列表示法來代表得到的 2 元樹

10
左鏈結代表
父子 關係
右鏈結代表
兄弟 關係
11
6.2.2 左子右弟表示法
練習:請比照投影片第 9 頁畫出投影片第 11 頁 (d)
之鏈結串列表示
經過以上轉換可知:2 元樹是很重要的樹狀結構
12
6.3 二元樹 (binary tree)
二元樹:

樹中每一節點最多有 2 個子節點


也就是說其分支度永遠小於等於 2

是一棵空樹或是由一個樹根以及兩個互相分離的二元樹(稱為左子
樹和右子樹)所組成

因為子樹有左右之分,二元樹又稱為有序樹(Ordered Tree)

二元樹可以是空集合,但只要是非空集合的樹至少要有一個樹根

如同串列,二元樹的節點的值依照應用的需求而定,可以排序或不
排序
13
二元樹的型態
只有一個樹根節點
歪斜樹 (Skewed Tree)



指樹根僅有一個子樹 (可能是左子樹或右子樹)
完滿二元樹(Full Binary Tree)

1.非終端節點都有兩個分支度的二元樹
2.完滿二元樹共有2K-1個節點,k為二元樹的深度
完整二元樹(Complete Binary Tree)

1.完整二元樹的樹葉節點可能位於不同階層上
2.與完滿二元樹非常相似,但節點個數少於2K-1
14
二元樹的型態
請問以上二元樹的型態為何?
15
二元樹的特性
1. 第 i 階層的總節點數小於等於 2i-1,i≧1。
2. 二元樹的節點總數少於 2k,k 為二元樹的深度,
k≧1
3. 樹葉節點總數等於分支度為2的節點總數加 1。
 以 圖 6.14(g) 為例,分支度為2的節點總數為 4,樹葉
節點總數為 5
16
6.4 二元樹的表示法

鏈結串列 (如 6.2 節)
root
左子樹鏈結 節點資料欄 右子樹鏈結
LLINK
data
RLINK


一維陣列
二維陣列
17
二元樹的鏈結串列表示法 (ch6_tree_1.java)

優點:容易利用新增、刪除、搬移節點來修改樹
18
二元樹的鏈結串列表示法 (ch6_tree_1.java)

此 (ch6_tree_1.java) 二元樹的特性:


左子樹的所有節點的資料值 < 父節點的資料值 <右子樹的
所有節點的資料值
方法




建構子
新增資料節點 : void addNode(int data)
在某個節點之下新增節點:
Node insertNode(Node node, int data)
顯示樹狀結構:void DisplayTree( )
1.
2.
3.

19
利用 nextLevelStack 堆疊來存放下一層節點
利用 currLevelStack 堆疊來存放還沒列印之同一層節點
利用深度來決定同一層節點的距離
刪除節點:比較難,後面 6.7 會教
二元樹的一維陣列表示法
第 i 個節點
20
二元樹的一維陣列表示法範例
沒用到
21
二元樹的一維陣列表示法(ch6_tree_2.java)


類似二元樹的鏈結串列表示法
方法:




建構子
新增資料節點 : void addNode(int data)
在某個節點 (以索引 i 代表) 之下新增其值為 data 之節點:
Node insertNode(int i, int data)
顯示樹狀結構:void DisplayTree( )
1.
2.
3.

22
利用堆疊來存放還沒列印之子樹的樹根
以 陣列 的索引來推導出各節點的深度
利用深度來決定同一層節點的距離
刪除節點:比較難,後面 6.7 會教如何在鏈結串列表示法
中刪除節點 (先跳過 ch6_tree_3.java)
二元樹的一維陣列表示法(ch6_tree_4.java)

排序二元樹資料的搜尋

23
void find(int data):
Idea: data 先跟樹根的值比,如果:
1. 相等:則傳回樹根的索引
2. data 比較大:到右子樹找
3. data 比較小:到左子樹找
作法:利用 索引值 current 來代表比到那一個節點
current 的初始值設為 1 ,表示為樹根
比較的方式:data 與 arr[current] 比
右子樹:將 current 設為 current*2+1
左子樹:將 current 設為 current*2
找不到的結束尋找條件:當 current > arr.length
二元樹的二維陣列表示法(ch6_tree_5.java)
24
二元樹的二維陣列表示法(ch6_tree_5.java)
0
25
二元樹的二維陣列表示法(ch6_tree_5.java)
0
相關方法類似二元樹的一維陣列表示法,
同樣以陣列 的索引(第一維)來推導出各節
點的深度
26
6.5 二元樹的追蹤(traversal)和應用
追蹤:拜訪所有節點並依序將各節點的資料印出
C
27
H
二元樹的追蹤(traversal)和應用
28
二元樹的追蹤(traversal)和應用
上述三種追蹤可歸納出以下幾點特性


樹根為前序追蹤的第一個節點,也是後序追蹤的最後一個
節點

已知前序追蹤與中序追蹤結果,便能決定出唯一的二元樹

已知後序追蹤與中序追蹤結果,便能決定出唯一的二元樹
29
二元樹的追蹤(traversal)和應用

例題[訂正課本]:某一二元樹的前序追蹤結果為
ABCDEFGH及其中序追蹤結果為 CBDAGFEH,請
畫出此二元樹
30
31
二元樹的追蹤和應用(ch6_tree_6.java)
32
練習

[類似課本原範例]:某一二元樹的前序追蹤結果為 A、
B、C、D、F、G、H、I、E 及其中序追蹤結果為 B、A
、F、D、H、G、I、C、E ,請畫出此二元樹。結果如
下,請畫出其推導步驟
A
B
C
D
F
G
H
33
E
I
ch6_tree_6.java

將 中置式運算式轉換成後置式運算式(不含左右括弧),再利用後置式(
由左至右判斷一個一個字母為運算子或運算元)轉換成一顆二元樹,其
樹葉節點為運算元,非樹葉節點為運算子,再利用此二元樹之中序、
前序、後序追蹤得到此運算式之不含左右括弧之中置式、前置式、後
置式表示法

例如:運數式A-B*(C+D)/E 的後置式 ABCD+*E/- ,其二元樹表示法:
A
/
*


34
後序追蹤: ABCD+*E/前序追蹤: -A/*B+CDE
B
E
+
C
D
作業
1.
2.
3.
35
請以鏈結串列建立一個如 p.17 的排序二元樹(程式請
將資料 data 改為整數),列印此二元樹,接著先找尋
‘I’ 及 ‘E’,再將 ‘I’ 放在 ‘E’ 之右子樹,再列印修改過之
二元樹
將上題改以一維陣列實作二元樹,再做一次
將上題改以二維陣列實作二元樹,再做一次