AA樹,2-3樹二叉化
阿新 • • 發佈:2019-01-28
AA樹,紅黑樹的變種
CLRS(演算法導論)上對RBT(紅黑樹,red-black tree)的講解相當好;
我這裡只能東施效顰,解釋一下紅黑樹的變種,AA樹;
正如RBT是由2-3-4樹演化而來,AA樹是2-3樹的二叉形式;
給出AA樹的定義:
1. AA樹是一顆維護了結點顏色(黑高)的二叉搜尋樹;
2. 任意一葉結點(T.nil,哨兵)到根結點路徑上黑結點個數相同(黑高相等,平衡原理);
3. 根結點為黑,葉結點(T.nil,哨兵)顏色為黑;
4. 紅結點兩子結點顏色為黑(子結點可能為葉結點);
5. 紅結點不得作為黑結點左子結點(與RBT不同);
給出一個AA樹樣例:
為了分析方便,我們把樣例轉化為類2-3樹形式,以便分析:
網上介紹AA樹大部分都是維護了結點的黑高;
我這裡沿用RBT的形式,維護結點的顏色;
AA樹中的搜尋很顯然,與普通二叉搜尋樹一樣;
下面給出兩個大頭:插入與刪除;
插入:
參考CLRS,給出虛擬碼:
Inset(T,t)
y=T.nil
x=T.root
while x≠T.nil
y=x
if t.key<x.key
x=x.left
else x=x.right
t.p=y
if y ==T.nil
T.root=t
else
if t.key<y.key
y.left=t
else y.right=t
t.left=T.nil
t.right=T.nil
t.color=red
Insert-Fixup(t)
這是插入的迭代寫法,考慮到迭代並不複雜,效率也很高,維護,除錯也方便,我這裡就不給出遞迴形式;
Insert中有一個Insert-Fixup,它是一個輔助過程,修復被破壞的紅黑性質;
修復的情況:
case 1: 紅結點做了其父左子結點 ,其中D,E結點顏色未知;
Case 1’ : D結點為黑
操作: 右旋x父結點後兩結點顏色互換,並將x指向原父結點;
Case 1”: D結點為紅
操作: 右旋父結點,剩下的交給Case 2處理;
Case 2: 紅結點右子結點為紅
操作: 左旋x的父結點後將x的右結點變為黑色;
以上操作完成後可能造成新的紅黑性質破壞,故x結點上移;
最後,將根結點顏色設為黑,修復完畢;
綜合考慮,給出Insert-Fixup虛擬碼:
Insert-Fixup(T,t)
while t.color==red
if y==t.pre.left
right-rotate(t.pre)
if t.right.color==black
t.color=black
t.right.color=red
else t=t.right
if t.right.color==red
left-rotate(t.pre)
t.right.color=black
t=t.pre
T.root.color=black
給出一個AA樹插入例項:
樣例插入結點8:
經Case 2 變為:
經Case 1’變為:
再經Case 2 變為:
經Case 1” 變為:
經Case 2 變為:
最後,設定根結點顏色:
好,介紹完了插入操作,下面是刪除操作;
我的刪除操作討論的情況很多,但保證正確清晰;
直接給出刪除和其呼叫的子過程的虛擬碼:
Transplant(T,x,y)
if x.pre==T.nil
T.root=y
else
if x==x.pre.left
x.pre.left=y
else x.pre.right=y
if y≠T.nil
y.pre=x.pre
好,我的刪除太醜了,等我再改改;