Download as pdf or txt
Download as pdf or txt
You are on page 1of 179

第六章

進階樹狀結構(Tree)
課程名稱:資料結構

授課老師:_____________
引線二元樹(Thread Binary Tree)
1. 解決Linked-List實作二元樹時,鏈結欄位浪費問題
2. 解決二元樹中序走訪需要額外記憶體問題(遞迴)

B C
A為資料值
A
D E
指向左子樹 指向右子樹

B C
若沒有右子樹
null null

D E 則指標指向空節點(null)

null null null null

若為終端節點,則左、右指標指向空節點(null)
引線二元樹(Thread Binary Tree)
A
A

B C B C

D E
null null

D E

null null null null

共有V = {A, B, C, D, E },|V| = n = 5 個節點,|E| = |V| - 1  因為 |V|= | E |+1

1. 總共開設欄位: 準備 (2*n) = 2* 5 = 10 個鏈結


2. 實際使用欄位: 使用 (n-1) = 4 個欄位

浪費的欄位 = 總共欄位 – 實際使用 = (2*n) – (n-1) = (n+1)


引線二元樹(Thread Binary Tree)
 優點:
◦ 減少鏈結的浪費
◦ 中序走訪,不需要堆疊

 缺點:
◦ 加入或刪除效率差
◦ 每個節點須再增加兩個欄位,紀錄是否為
引線,0表示否,1表示是。
引線二元樹資料結構

用一個額外的 Bit 判斷指標內容是 Link 還是 Thread


引線二元樹的資料結構如下:
當 lthread=0, leftchild 存放是指標 ; lthread=1, rightchild 存放是引線
當 rthread=0, leftchild 存放是指標 ; rthread=1, rightchild 存放是引線
引線二元樹資料結構
首節點(Head)

根節點(root)

中序追蹤: D B A C,
該節點有小孩則不用引線, 反之則需要, 當有需要用引線時,則分別指向該節點的
中序立即前行者 (Predecessor) 或是中序立即後繼者 (Successor)
比如B的中序立即前行者=D,中序立即後繼者=A
引線二元樹資料結構
首節點(Head)

根節點(root)

中序追蹤: D B A C,
第一個開始節點, D的中序立即前行者=Head, 中序立即後繼者=B
最後一個節點, C的中序立即前行者=A, 中序立即後繼者=Head
引線二元樹的中序走訪
首節點(Head)

根節點(root)

利用引線二元樹來進行中序追蹤完全不需要堆疊喔!!! 速度相當快

從Head開始走最後走回Head結束
引線二元樹的中序走訪
Thread_Inorder( Tree )
Begin
Temp = Tree ;
while (True)
begin
Temp = inorder_successor(temp) ;
if (Temp == Head) break;
print( temp -> data );
end
end
引線二元樹的中序走訪
找中序的立即後續節點
Tree inorder_successor(Tree)
Begin
Temp = Tree -> rightChild ;
if (Tree->rthread == 0)
Begin
while ( Temp -> lthread == 0)
Temp = Temp -> leftchild ;
End
return Temp ;
End
引線二元樹的新增節點
練習:自己畫畫看
6-6.3 最小-最大堆積樹
(Min-Max Heaps Tree)
【定義】最小-最大堆積樹(Min-Max Heaps Tree)是一個完整二元樹。
此二元樹是交替min level與max level的階層方式呈現,其中樹根為
最小鍵值。 階度

10 1 min(最小)

90 80 2 max(最大)

12 15 20 25 3 min(最小)

50 60 40 55 4 max(最大)

【建立規則】

1. 階度1的鍵值 < 階度3的鍵值 < 階度5的鍵值…< 階度n的鍵值(n為奇數)

2. 階度2的鍵值 > 階度4的鍵值 > 階度6的鍵值…> 階度n的鍵值(n為偶數)


【實例】請問下列的二元樹是否為最小-最大堆積樹呢?為什麼?

階度

10 1 min(最小)

90 80 2 max(最大)

12 5 20 25 3 min(最小)

50 60 40 55 4 max(最大)

【解答】
(1)此棵二元樹不是最小-最大堆積樹。
(2)因為階度3的右子樹之鍵值5比階度1的樹根10小,因此,
它是違反最小-最大堆積樹的建立規則之第1條。
6-6.3 最小-最大堆積樹
(Min-Max Heaps Tree)
最小最大堆積樹加入和刪除和一般堆積樹相同,加入時,將資料添加
於樹的最後,然後再進行調整。移除時,樹根的移除則利用最後一個
節點來取代,然後再進行調整。 階度

10 1 min(最小)

90 80 2 max(最大)

12 15 20 25 3 min(最小)

50 60 40 55 4 max(最大)

【建立規則】

1. 階度1的鍵值 < 階度3的鍵值 < 階度5的鍵值…< 階度n的鍵值(n為奇數)

2. 階度2的鍵值 > 階度4的鍵值 > 階度6的鍵值…> 階度n的鍵值(n為偶數)


Min-Max Heap 調整

1. 先檢查輸入x落在哪一個Level (min level , max level)

2.考慮x的父節點位於哪個層, max/min level:

min level: 如果x比父節點小, 則x與父節點互相交換, 並向上驗證。

max level:如果x比父節點大, 則x與父節點互相交換, 並向上驗證。


6-6.4 最小-最大堆積樹中加入節點
【規則】
1.遵循完整二元樹的規則(依序加入,不需比較)
2.進行調整(遵循Min-Max Heaps Tree的規則)
【題目】請在下列的最小-最大堆積樹中,插入一個節點5。
10

90 80

12 15 20 25

50 60 40 55
N2>n4>n3>n1
6-6.4 最小-最大堆積樹中加入節點(續)

步驟一:加入5

步驟二:進行調整(請先檢查目前在哪一層min or max)
持續和父節點逐一比對,直到root為止

交換

交換
6-6.4 最小-最大堆積樹中加入節點(續)

5和80比較, 滿足條件不需要改變。

交換
額外範例: 下圖 加入100 呢?

100
6-6.5 最小-最大堆積樹中刪除節點
【規則】
1. 刪除根節點
2. 選擇樹的最後一個節點來補位
3. 尋找根節點以下的最小鍵值與根節點交換
4. 再進行調整
【題目】請在下列的最小-最大堆積樹中,刪除一個節點10
10

90 80

12 15 20 25

50 60 40 55
6-6.5 最小-最大堆積樹中刪除節點(續)
步驟一:刪除10
移除
10

90 80

12 15 20 25

50 60 40 55

步驟二:選擇最後一個節點來補位
55

90 80
補位

12 15 20 25

50 60 40
6-6.5 最小-最大堆積樹中刪除節點(續)
步驟三:尋找根節點以下的最小鍵值與根節點交換(55與12交換)
根節點
55

90 80
交換
最小鍵值 12 15 20 25

50 60 40

步驟四:進行調整(55與50交換)

交換
10
刪除90
90 80

12 15 20 25

50 60 40 55
交換
練習時間:

30

19
雙堆積 Deap
(Double-ended Heap)
Deap 是一個Complete Binary Tree 且滿足:

(a) 樹根節點不存放任何資料

(b) Root的左子樹為min-heap

(c) Root的右子樹為max-heap

令 i 為min-heap的一個節點編號,j 為max-heap的一個節點編號,則

Deap[i] ≤ Deap[j], 若左子樹在右子樹找無對應節點,則取右子樹節點

的父節點對應。
雙堆積 Deap
(Double-ended Heap)

minimum maximum
雙堆積 Deap
(Double-ended Heap)
加入70
刪除最小值5
練習時間:
Symmetric Min-Max Heap
是一個 Complete Binary Tree, 樹根不存放Data,滿足:

1.左兄弟 ≤ 右兄弟

2.節點x的祖父的左子點必須 ≤ x

3. 節點x的祖父的右子點必須 ≥ x
很像Deap但不是喔!!!
Insert x in an SMMH
今天加入一個數值2
50
Delete min in an SMMH
刪除數值2
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

4 80

20 70 5 9

30 50
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

30

加入30
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

30 20 20 30

加入20 調整後
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

20 30 20 50

50 30

加入50 調整後
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

20 50 5 50

30 5 20 30

加入5
調整後
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

5 50 4 50

20 30 4 20 30 5

加入4 調整後
依序插入30,20,50,5,4,9,70,2,80 請劃出最
後SMMH圖

剩下來的………自己完成~~~~
二元樹的應用
 算式樹 (Expression Tree)
 霍夫曼樹 (Huffman Tree)
 決策樹 (Decision Tree)
 遊戲樹 (Game Tree)
 延伸二元樹 (Extended Binary Tree)
 擴張樹 (Spanning Tree)
 二元搜尋樹 (Binary Search Tree)
 平衡樹 (AVL Tree)
二元樹應用-運算樹
(Expression Tree)
(1) leaf nodes為運算元 (operand),而非leaf
nodes 為運算子 (operator)。
(2) 子樹為子運算式,樹根為運算子。

(x+y+z*n)
二元樹應用-霍夫曼樹
(Huffman tree)
霍 夫 曼 樹 (Huffman tree) 是 根 據 霍 夫 曼 碼
(Huffman coding) 技術所建構的編碼樹,霍夫曼
碼是一種不固定長度的編碼技術,符號的編碼
長度與出現頻率成反比,屬於頻率相關編碼
(frequency dependent encoding)
二元樹應用-霍夫曼樹
(Huffman tree)
 建構一棵霍夫曼樹(Huffman tree):

Step1.先統計每個英文字母的出現頻率。

Step2.採用霍夫曼演算法(Huffman's Algorithm)
a.合併頻率最低的兩個,其頻率相加並建立一個父節點。
b.重覆步驟a,合併到只剩下一個節點為止。
6-10 霍夫曼樹 Huffman Tree
 建立一最佳化二元樹

1
1

2
3 2
3
Why?

儲存和搜尋都很差!!! 儲存和搜尋都very good!!!


符號 A B C D E
出現頻率 0.19 0.09 0.23 0.37 0.12

0.40 0.60

A C E
0.19 0.21 0.23 0.37

B 0.09 0.12 D
1.0

0.40 0.60

A C E
0.19 0.21 0.23 0.37

B 0.09 0.12 D

Huffman Tree
0 1

0 1 0 1
A

0 C E
1
B D

文字: ABC
編碼: 00 010 10

出現次數越多的符號,用較少的位元去編碼,以
減少傳輸資料量。
二元樹應用-決策樹 (Decision Tree)
決策樹 (Decision Tree) ,他是一種利用樹狀結
構的方式來討論一個問題的各種情況的可能性
,以作為決策的參考。

三個相異數 a, b, c 比大小 a>b

N
Y

b>c c>b
Y N Y N

a>b>c c>b>a
c>a c>a
Y N Y N

c>a>b a>c>b b>c>a b>a>c


二元樹應用-遊戲樹 (Game Tree)
二元樹應用-遊戲樹 (Game Tree)
延伸二元樹 (Extended Binary Tree)
Def: 一個 n 個節點的二元樹,以Link list表示, 會
有 n+1條空Link, 今在空Link上加上特別節點, 稱
為外部節點(External Node), 其餘Nodes稱為內部
節點(Internal Nodes)。

a 內部節點共5個, {abcde}

b
c

d e
f g

h I j k

外部節點 (樹葉節點、終端節點) 共6個, {fghijk}


延伸二元樹 (Extended Binary Tree)
 代號I: 稱為內部路徑長度

 代號E:計算外部路徑長度

 定理: E= I + 2 * n , n為內部節點個數。
範例1: 0
n: 內部節點個數為 5

1
1

2 2

2 2

3 3 3 3

內部路徑長度 I = 0 + 1+ 1 + 2 + 2 = 6
外部路徑長度 E = 3 + 3+ 3 + 3 + 2 + 2 = 16

E = I+2*n
= 6+2*5
= 16
範例2: 一顆二元歪斜樹: (藍色內部節點共有 n 個節點)

0
n(n  1)
1
I  0  1  2    (n  1) 
2
1
2 E  1  2    (n  1)  n  n
2  0  1  2    (n  1)  n  n
(n  1)n
3   2n
n-2 2
 I  2n
n-1
(n-1)

n n
證明:
n0 = n2 +1

∵ n = n0 +n1 + n2 ----(1)
|E| = n1 + 2n2 ---(2)
|E| = |V| -1, |E| = n-1 ---(3)
由(2)(3) n-1 = n1+2n2, n= n1+2n2 +1 ---(4)
由(1)(4), n0 +n1 + n2 = n1+2n2 +1
n0 = n2 + 1
Proof: E = I + 2*n
使用數學歸納法證明:

假設左子樹的內部節點數為 nL,內部路徑長為IL, 外部路徑長為EL


右子樹的內部節點數為 nR,內部路徑長為IR, 外部路徑長為ER

1. 當內部節點數為0, 此樹為空樹 (Empty tree), E = I = 0, 所以E = I + 2*N成立

2. 假設內部節點數為(n-1),此定理成立。
左子樹滿足: EL=IL + 2*nL
右子樹滿足: ER=IR + 2*nR

3. 當內部節點數為 n 時 :
I = IL + IR + nL + nR
E = EL + (nL+1) + ER + (nR+1)
E = EL + ER + (nL+1) + (nR+1), 因為 EL = IL + 2*nL 且 ER = IR + 2*nR
E = (IL + 2*nL) + (IR + 2*2nR) + (nL+1) + (nR+1)
= (IL + IR + nL + nR) + 2 (nL+nR+1), 因為 n = nL+ nR + 1
= I + 2 * n 得證
E = I + 2*n
0
1
1
2 n(n  1)
2 I  0  1  2    (n  1) 
2
3 n(n  1)
n-2 E  1  2  3    (n  1)  n  n   2n
2
n-1
(n-1)
n n

0
1
2 1
2

n-2 3

(n-1) (n-1) 0

左子樹 右子樹
E = I + 2*n

0 n(n  1)
1 I  0  1  2    (n  1) 
1 2
2
2

n-2 3
左子樹-內部節點 nL: (n-1) 個
(n-1) (n-1) 左子樹-內部路徑 IL: 0+1+2+…+ (n-2)
n(n  1)
  (n  1)
左子樹 2

右子樹的內部節點 nR: 0 個
0
右子樹的內部路徑 IR: 0

右子樹
I = (IL + nL) + (IR + nR)
 n(n  1)  n(n  1)
I  (n  1)  (n  1)   0  0 
 2  2
E = I + 2*n

0
1 左子樹-外部路徑EL:
2 1 EL  1  2  3    (n  2)  (n  1)  (n  1)
2 (n  1)(n  2)
  2(n  1)
n-2 3 2

(n-1) (n-1)
左子樹

右子樹-外部路徑ER:
0
ER  0
右子樹
E = EL + (nL+1) + ER + (nR+1)
(n  1)(n  2)
E  2(n  1)  (n  1  1)  0  (0  1)
2
n(n  1)
E  2n  I  2n
2
自己練習看看:
0

1
1

2 2

2 2

3 3 3 3

內部路徑長度: I  0 1 1 2  2  6
外部路徑長度: E  3  3  3  3  2  2  16
0

0
1 1

2 2 2 2 1 1
左子樹 右子樹

nL=3 nR=1
IL=0+1+1=2 IR=0
EL=2+2+2+2=8 ER=1+1=2

I = IL + IR + (nL + nR) = 2 + 0 + 3 + 1 = 6
E= EL + ER + (nL+1) + (nR+1) = 8 + 2 + (3+1) + (1+1)
= 16
6-7 高度平衡樹 ( AVL Tree )
在前面章節中所介紹的二元搜尋樹,如果左子樹與右子樹的高度能夠

維持在平衡的情況時,則其搜尋時間會減低。因此,在本單元中將介

紹AVL Tree的平衡樹,就是調整二元搜尋樹的左右子樹的高度,來達

到二元樹的平衡,因此,我們將AVL Tree又稱為高度平衡二元搜尋樹。

基本上,AVL樹必須要合乎下列兩個條件:

1.是一種二元搜尋樹。

2.高度須保持平衡狀態。
【定義】為一棵高度平衡的二元搜尋樹,可以為空,若不為空,
則必須滿足以下兩個條件:
1. 左子樹(TL)和右子樹(TR)都是高度平衡樹。如下圖所示。
2. 左、右子樹的高度差必須要小於或等於1。

hL 左子樹 右子樹 hR
(TL) (TR)

其中 hL 和 hR 分別為 TL 和 TR 的高度。
6-7.1 平衡因子(Balance Factor)
【定義】在二元樹中,一個節點 T 的平衡因子 ( Balance Factor ;BF)
的定義為 hL - hR ,其中hL和hR 分別為節點T的左子樹和右子
樹的高度。對 AVL 樹中的任一節點 T 而言,BF(T)=0,-1或1
等三種情況。如下圖所示。

第一種情況BF(T)=1 第二種情況BF(T)=-1 第三種情況BF(T)=0


1
A
-1 0

在上圖中,每一個內部節點的左子樹與右子樹的高度相差最多是1,因
此是AVL樹。
【不是AVL樹情況】
hL - hR = 2
A
-2 0
hR =1
1
hL=3
0

在上圖中,因為節點A的左子樹的高度為3,右子樹的高度為1,所

以相差2。
6-7.2 AVL 樹的不平衡點調整
之四種型式
我們在進行AVL樹的加入與刪除動作時,往往會造成不平衡狀態,

因此,我們必須要加以調整,最後必須要保持平衡狀態。

我們將不平衡狀態分為四種:

(一) LL型(Left-Left)

(二)RR型(Right-Right)

(三) LR型(Left-Right)

(四)RL型(Right-Left)
【調整原則】
LL, LR, RL, RR標線牽涉到三個節點。而三個節點中,將中間鍵
值往上拉,小的放左邊,大的放右邊。

(一) LL型(Left-Left) (二)RR型(Right-Right)

小 A
大 A R
B B
L 調整
中 B 中 B
調整 R A C
L C A
小 C 大 C

(三) LR型(Left-Right) (四)RL型(Right-Left)

大 小 A
A R
C C
L 大 B
小 B 調整
調整 L
R
B A A B
中 C 中 C
(一)LL型(Left-Left)
1.新節點C加入到節點B的左子樹
2.將中間鍵值(B節點)往上拉,小(C節點)的放左邊,大(A節點)的順時
針旋轉後,放右邊。

1 2
Œ 上拉
A A 大
加入C 1 LL調整 A 完成
0 L B
B B 中
0 B
L C A
平衡的子樹 C小
C  順時針旋轉 重新平衡的子樹
失去平衡的子樹
【實例】

1 2
Œ 上拉
10 10 大
加入3 1 LL調整 10 完成
0 L 5
5 5 中
0 5
L 3 10
平衡的子樹 3 小
3  順時針旋轉 重新平衡的子樹
失去平衡的子樹
(2)RR型(Right-Right)
1.新節點C加入到節點B的右子樹
2.將中間鍵值(B節點)往上拉,大的放右邊(C節點),小的逆時針旋
轉後,放左邊(A節點)。

-1 -2 Œ 上拉
B
A A小 A 完成
加入C RR調整
0 R -1 A C
B B中 B
重新平衡的子樹
平衡的子樹 R 0 0
C大  逆時針旋轉 C
失去平衡的子樹
【實例】

-1 -2 Œ 上拉
5
3 3 小 3 完成
加入10 RR調整
0 R -1 3 10
5 5 中 5
重新平衡的子樹
平衡的子樹 R 0 0
10 大  逆時針旋轉 10
失去平衡的子樹
(3)LR型(Left-Right)
1.新節點C要被加入到A節點的左兒子(B節點)的右子樹
2.將中間鍵值(C節點)往上拉,小的放在C節點的左邊,大的放在C
節點的右邊。

1 2
C
A A大 A 完成
加入C -1 LR調整
0 L Œ 上拉 B A
B B 小 B
R 重新平衡的子樹
0
平衡的子樹 C中 C
逆時針旋轉 Œ 順時針旋轉
失去平衡的子樹
【實例】
1 2
5
10 10 大 10 完成
加入5 -1 LR調整
0 L Œ 上拉 3 10
3 3 小 3
R 重新平衡的子樹
0
平衡的子樹 5 中 5
Œ 逆時針旋轉  順時針旋轉
失去平衡的子樹
(4)RL型(Right-Left)
1.新節點C要被加入到A節點的右兒子(B節點)的左子樹
2.將中間鍵值(C節點)往上拉,小的放在C節點的左邊,大的放在C
節點的右邊。

-1 -2
A C
A 加入C A 小
完成
RL調整
0 1 Œ 上拉 A B
R B
B B大
0 L 重新平衡的子樹
平衡的子樹 C
C 中 逆時針旋轉 Œ 順時針旋轉
失去平衡的子樹
【實例】
-1 -2
3 5
3 加入5 3 小
完成
RL調整
0 1 Œ 上拉 3 10
R 10
10 10 大
0 L 重新平衡的子樹
平衡的子樹 5
5 中 Œ 逆時針旋轉  順時針旋轉
失去平衡的子樹
6-7.3 AVL Tree 之平衡調整步驟
【作法】
1. 找出關鍵路徑,計算路徑上每一個節點的平衡因子。
2. 從樹根開始,找到最後一個平衡因子為 2 以上的節點,
稱之為關鍵節點。
3. 決定調整方式(LL, RR, LR, RL)。
4. 進行調整,必須保持二元搜尋樹的定義。
【實例1】依序輸入5個資料分別為:2, 4, 6, 8, 10來建立二元搜尋樹
【解答】
加入2 加入4 加入6 加入8 加入10
2 2 2 2 2

4 4
4 4

6 6 6

8 8

10

分析:
hL=0並且hR=4,所以| hL - hR | = | 0-4 | >=1
所以,產生斜曲樹的現象,因此,5筆資料最多需要比較5次才能找到。
【實例2】依序輸入5個資料分別為:2, 4, 6, 8, 10來建立平衡二元樹
【解答】
加入2 加入4 加入6 0
2 -1 -2
2 4
2
0
R
-1 RR型調整 0 0
4 4 2 6
R
0
重新平衡的子樹
平衡的子樹 6
不平衡的子樹

加入8 加入10 -1
-2
4
RR型調整
4
-1
0 -2 0 0
4
2 6 2 8
0 -1 R
2 6 -1
0
0
8
0 R 6 10
8 0
重新平衡的子樹
平衡的子樹 10
不平衡的子樹
M元搜尋樹
 m元搜尋樹 (m-way search tree ) 指的是
空集合或滿足下列條件的搜尋樹:
M元搜尋樹(加入)
 如同二元搜尋樹一般加入動作,因此
會造成樹的不平衡。
題目: 三元搜尋樹 m=3,依序加入30, 80, 10, 50, 120, 20, 4

30 80

10 20 50 120

最後結果圖
M元搜尋樹(刪除)
 如同二元搜尋樹刪除動作。如果是leaf node
直接刪除,如果是內部節點則由其左子樹最
大或右子樹最小來取代。
題目: 刪除三元搜尋樹 m=3,刪除4

30 80

10 20 50 120

最後結果圖
M元搜尋樹(刪除)
 如同二元搜尋樹刪除動作。如果是leaf node
直接刪除,如果是內部節點則由其左子樹最
大或右子樹最小來取代。
題目: 刪除三元搜尋樹 m=3,刪除30

最後結果圖
B Tree (亦稱m-way tree)
定義: B-Tree 是一個 平衡 m-way search tree。
B-Tree 可以為空,若不為空,則滿足下面條件:

 每一個節點最多含有 m-1 個鍵值

 除了樹根節點和樹葉節點外的每一個節點,其餘節點
的分支度須滿足 m/2 ≦ degree ≦ m 。

 所有樹葉節點均在同一層 (Balance),亦即從樹根節點
到樹葉節點所經之路徑長度均相同
B Tree (亦稱m-way tree)
 B Tree 每一個節點,最多含有 m-1 個鍵值。

 樹的高度增加只發生於樹根節點一分為二時

 B tree of order 3又稱2-3 tree;


B tree of order 4又稱2-3-4 tree
T
18 75
P0,1 P2,3
P1,2
T1 T2 T3
8 10 31 79 89

λ λ λ λ λ λ λ λ

2-3 Tree
B-Tree 表示方式 (2-3-4 tree)
B-Tree 定理
高度為h的B Tree (m-way Search Tree)

最多的Node個數 = m0+m1+m2+…+mh-1
= (mh-1)/(m-1)

最多的Data個數 = (m-1)* (mh-1)/(m-1)


=(mh-1)
B樹
 m 階 B 樹的節點結構
K1 K2 K3 ... Km-1

P0,1 P1,2 P2,3 Pm-2,m-1 Pm-1,m

 4階B樹
100

31 57 91 150 200

8 35 40 45 58 63 95 121 140 158 183 205

λ λ λ λ λ λ λ λ λ λ λ λ λ λ λ λ λ λ λ
如何在m階B樹上插入鍵值
 新鍵值插入在樹葉節點。

 若樹葉節點仍有空位,則直接插入。

 若樹葉節點已經額滿,則需進行分裂,
將此節點一分為二,並將中間的鍵值
(第 m/2 個) 提昇至父節點。若父節點
也額滿,則需重複分裂的動作。
插入鍵值
 m=5
 鍵值個數最多4個

 Insert 21
插入鍵值
 Insert 67
如何在m階B樹上刪除鍵值
 當欲刪除的鍵值位於非樹葉節點時,以其中序前行
者或後繼者交換,則所有刪除的問題皆可轉換為刪
除樹葉節點的鍵值。

 若刪除鍵值後的節點剩下k個鍵值(k m/2-1),直接
刪除此鍵值。

 若刪除鍵值後的節點剩下k個鍵值(k< m/2-1),需要
進行旋轉或合併。 兄弟或父親

除了樹根節點和樹葉節點外的每一個節點至少都含有 m/2 個子節點,最多有 m 個子節點。


刪除鍵值
 m=3
a
80
b c
50 70 100 150
d e f g h i
30 40 55 72 75 90 115 175

 Delete 40
a
80
b c
50 70 100 150
d e f g h i
30 55 72 75 90 115 175
刪除鍵值
 Delete 55
a
80
b c
50 72 100 150
d e f g h i
30 70 75 90 115 175

 Delete 90
a
80
b c
50 72 150
d e f h i
30 70 75 100 115 175
刪除鍵值
 Delete 80
a
100
b c
50 72 150
d e f h i
30 70 75 115 175

a a
80 80
b c b c
50 72 150 50 72 150
d e f h i d e f h i
30 70 75 100 115 175 30 70 75 100 115 175
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

加入34
34

加入70

34 70
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

加入11

34

11 70

加入22
34

11 22 70
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

加入83
34

11 22 70 83

加入94
34 83
34

11 22 70 83 94
11 22 70 94
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

加入62

34 83

11 22 62 70 94
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

加入65
34 83

11 22 62 65 70 94

65

34 65 83
34 83

11 22 62 70 94
11 22 62 70 94
B-Tree (2-3 Tree)
題目: 建立一2-3 樹, 依序加入34, 70, 11, 22, 25, 83, 94, 62, 65

65

34 83

11 22 62 70 94

最後結果
B-Tree (2-3 Tree)
題目: 從下面B tree 進行刪除

65

34 83

原本圖
22 62 70 94

刪除11
B-Tree (2-3 Tree)
65

題目: 從下面B tree 進行刪除22 83

65
34 62 70 94

34 83
旋轉 x
合併 o

22 62 70 94
65 83
原本
先向左右兩邊借(旋轉)
不能再父子合併(合併) 34 62 70 94
62
B-Tree (2-3 Tree)
34 83
題目: 從下面B tree 進行刪除65

65 22 70 94

34 83
旋轉 x
合併 o

22 62 70 94
62 83
原本
先向左右兩邊借(旋轉)
不能再父子合併(合併) 22 34 70 94
70
B-Tree (2-3 Tree)
34 83
題目: 從下面B tree 進行刪除65

65 22 62 94

34 83
旋轉 x
合併 o

22 62 70 94
34 70
原本

22 62 83 94
紅黑樹 (Red-Black Tree)
紅黑樹是一棵Binary Search Tree且滿足:
 每個節點的顏色非黑即紅
 Root一律是黑色節點
 每個 Leaf (null 值) 視為黑色
 任何路徑上不可出現連續的紅色節點, No red-red Parent-Child
 樹上的任何一個節點,往下到達不同 Leaf node 的 simple path,皆
具有相同數量的黑色節點。

NIL
NIL

NIL

NIL NIL NIL NIL

不是紅黑樹 是紅黑樹
Black height: Bh(x) = 從節點x往子孫nil節點共經歷多少黑色區塊

nil節點的black height為 0
Rotate:

Node

Node
Right Rotate:
Left Rotate:
紅黑樹 (新增)
新增方式大致與二元搜尋樹一模一樣: (差別在於塗色和旋轉)

Step1: 產生一顆空樹(Empty) T , 第一個節點為樹根 (root) 標示為黑色

Step2: 凡加入一個新節點 x, 則將其塗成紅色, 並判斷下面條件:


if (x 節點的父節點 (parent node) 為紅色 )
if ( x 的 伯父節點 (uncle node) 為紅色)
重新塗色
if (x 的 伯父節點 為黑色 或 沒有伯父節點 )
重新塗色 + 旋轉
else
當 x 節點的父節點 p 為黑色,無需做任何處置
例子1: 依序加入 8 和 26

10 10
10 加入 8 加入 26
8 8 26
NIL

NIL NIL
NIL NIL NIL NIL NIL NIL
Case1:
X 的父親節點 (parent node) 為紅色 且 X 的伯父節點
(uncle node) 亦為紅色
current current

X’s Parent X’s uncle X’s Parent X’s uncle

current current

轉換前 轉換後

重新塗色:
X‘s parent B -> 黑, X’s uncle C-> 黑, X's grandparent A-> 紅

因為 grandparent 節點變成紅色,所以需要再往上層再做一次重複的檢查
例子2: 加入5

10

10
8 26

8 26
5
NIL NIL NIL

NIL NIL NIL NIL


NIL NIL

10 10

8 26 8 26

5 5
NIL NIL NIL NIL NIL NIL

NIL NIL NIL NIL


Case2:
X 的父親節點 (parent node) 為紅色, 且 X 的伯父節點 (uncle node) 為黑色或沒
有;X和X的父親節點皆非同右子樹或皆同左子樹旋轉後進入Case3

Left Rotate(B)
current current

原始
旋轉後

Right Rotate(B)
current current
Case3:
X 的父親節點 (parent node) 為紅色,且 X 和父親節點皆為左子樹或接
同為右子樹,且 X 的伯父節點 (uncle node) 為黑色或沒有

A A

B C B C

Step1:
X current recolor X current

A A

C B C B

current X Step1: current X


recolor
A
B

B C X A

Step2:
X current Right rotate(A) C
current

B
A

A X
C B
Step2:
Left rotate(A)
C
current X current
10
例子3: 加入7
8 26
10
5
加入7
8 26 NIL NIL NIL

7 current
5 NIL

NIL NIL NIL


NIL NIL

10 Left rotate(5)

8 26

Case3 7
NIL NIL NIL

current 5
NIL

NIL NIL
10
10

8 26
8 26

7
Recolor 7
NIL NIL NIL
NIL NIL NIL
current 5
current 5
NIL
NIL

NIL NIL
NIL NIL
Case3
10

8 26 10

7 Right rotate(8) 7 26
NIL NIL NIL

current 5 current 5 8
NIL NIL NIL

NIL NIL
NIL NIL NIL NIL
舉例 例子4: 依序加入30, 28

10 10

7 26 加入30
7 26
current
5 8 5 8 30
NIL NIL
NIL

NIL NIL NIL NIL


NIL NIL NIL NIL NIL NIL
舉例

10 10

7 26 加入28 7 26

5 8 30 5 8 30
NIL NIL

28
NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL

current
NIL NIL
舉例

10 10

7 26 Right Rotate(30) 7 26

5 8 30 5 8 28
NIL NIL

28 30
NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL
current

NIL NIL NIL NIL

Case2: Case3:
舉例

10 10

7 26 7 26

Recolor
5 8 28 5 8 28
NIL NIL

30 30
NIL NIL NIL NIL NIL current NIL NIL NIL NIL NIL
current

NIL NIL NIL NIL

Case3:
舉例

10
10

7 26 current
Left rotate(26) 7 28

5 8 28
NIL 5 8 26 30

current
30
NIL NIL NIL NIL NIL current
NIL NIL NIL NIL NIL NIL NIL NIL

NIL NIL 結果
Case3:
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 10 current 10 10 current

NIL NIL NIL NIL

Insert 20
10

20 current
NIL

NIL NIL
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 30

10

20
20
NIL
10 30 current
30 current
NIL

NIL NIL NIL NIL


NIL NIL
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 40

20 20 current

10 30 10 30

40 40
NIL NIL NIL current NIL NIL NIL

NIL NIL NIL NIL


例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 50

20 20

10 30 10 40

current
40 30 50
NIL NIL NIL NIL NIL

50 current
NIL NIL NIL NIL
NIL

NIL NIL
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 60

20 20

10 40 10 40 current

30 50 30 50
NIL NIL NIL NIL

60 current 60
NIL NIL NIL NIL
NIL NIL

NIL NIL NIL NIL


例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 55

20 20

10 40 10 40

30 50 30 55
NIL NIL NIL NIL
curren
60 50 60
NIL NIL NIL NIL NIL

current 55
NIL NIL NIL NIL NIL

NIL NIL
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 80

20 20

10 40 10 40

30 55 30 55 current
NIL NIL NIL NIL

50 60 50 60
NIL NIL NIL NIL

80 current 80
NIL NIL NIL NIL NIL NIL

NIL NIL NIL NIL


例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

20
40

10 40 20 55 current

30 55 current 10 30 50 60
NIL NIL

50 60 80
NIL NIL NIL NIL NIL NIL NIL NIL NIL

80
NIL NIL NIL NIL NIL

NIL NIL
例子5: 依序新增10, 20, 30, 40, 50, 60, 55, 80, 90

Insert 90
Searching Insert Delete
AVL Tree O(log n) O(log n) O(log n)
Red-Black Tree O(log n) O(log n) O(log n)

新增刪除 Red-Black tree 比較好 O(log n)

搜尋資料 AVL Tree 比較快


紅黑樹 刪除
1. 執行標準BST的刪除程序 (In-order traversal)

2. 簡單狀況: : X 或 Y 其中一個是紅色

3. 複雜情況: : X 及 Y 都是黑色 (6種情況)

Y
要刪除的資料 X
NIL
NIL NIL
Y
NIL NIL
Simple case: X 或 Y 其中一個是紅色

可以選擇節點9或是節點12 來取代節點10
Simple case: X 或 Y 其中一個是紅色
Complex case: A 和 B 都是黑色 (六種情況)
Complex case: A 和 B 都是黑色

白色節點 C可以是表示 黑色 或是 紅色
Case1: 兄弟 sibling 是紅色

Double black
繼續存在,需要再校正

Step1: 將sibling塗成黑色:node(E)塗成黑色;
Step2: 將current之parent塗成紅色:node(C)塗成紅色;
Step3: 對current之parent做Left Rotation:對node(C)做Left Rotation;
Step4: 將sibling移動到current->parent的rightchild:將sibling指向node(D)。

Case1,修正後,將進入Case2、Case3或Case4;
刪除6
將sibling塗成黑色
將current之parent塗成紅色
10

parent
8 12
current sibling

9
NIL NIL
NIL

NIL NIL

對current之parent做Left Rotation 進入至Case2


進入下一個範例
刪除18
parent
current
sibling

將sibling塗成黑色
將current之parent塗成紅色
parent
current
sibling

對current之parent做Right Rotation 進入至Case2


Case2: sibling 是黑色, 並且sibling之兩個 child皆為黑色

Step1: 將sibling塗成紅色:node(E)塗成紅色;
Step2: 將current移至currnet的parent:current移至node(C)。
Case2: sibling 是黑色, 並且sibling之兩個 child皆為黑色
Case 2-1: current->parent 是紅色

Case 2-2: current->parent 是黑色 Double black


繼續存在,需要再校正
進入至Case2
Case3: 若sibling為黑色,再加上滿足下面其中一個條件:
(一) 當sibling位於 Left subtree, sibling 的 leftchild為黑色, rightchild為紅色
(二) 當sibling位於Right subtree, sibling 的 leftchild為紅色 , rightchild為黑色

Double black
繼續存在,需要再校正

Step1: 將sibling之leftchild塗成黑色:node(D)塗成黑色;
Step2: 將sibling塗成紅色:node(E)塗成紅色;
Step3: 對sibling進行Right Rotation:對node(E)進行Right Rotation;
Step4: 將sibling移至current->parent的rightchild:將sibling移至node(D)。

經過以上修正步驟,sibling之rightchild成為紅色,便進入Case4
刪除25
將sibling之rightchild塗成黑色
將sibling塗成紅色
20 parent

18 sibling
current
NIL

15
NIL

對sibling進行Left Rotation NIL NIL

進入case4
Case4: 若sibling為黑色,再加上滿足下面其中一個條件:
(一) 當sibling位於 Left subtree, sibling 的 leftchild為紅色
(二) 當sibling位於Right subtree, sibling 的 rightchild為紅色

Double black 解除

1. 將sibling塗成current之parent的顏色:
若node(C)是紅色,則將node(E)塗成紅色;
若node(C)是黑色,則將node(E)塗成黑色;
2. 將parent塗成黑色:node(C)塗成黑色;
3. 將sibling之rightchild塗成黑色:node(F)塗成黑色;
4. 對parent進行Left Rotation:對node(C)做Left Rotation;
5. 將current移至root,把root塗黑。
進入case4

將sibling塗成current之parent的顏色
將parent塗成黑色
將sibling之leftchild塗成黑色
對parent進行Right Rotation
18 current

15 20

NIL NIL NIL NIL

將current移至root,把root塗黑
進入下一個範例
刪除2
將sibling塗成current之parent的顏色
將parent塗成黑色
將sibling之rightchild塗成黑色
對parent進行Left Rotation
15 current

parent
6 18

10 sibling
NIL NIL NIL

NIL NIL

將double black變成單一black
將current移至root,把root塗黑
總結

You might also like