演算法導論 紅黑樹

2021-08-25 02:03:08 字數 3274 閱讀 4625

原文**:

組內培訓,講紅黑樹,找出演算法導論,啃了乙個週末,其中插入結點很簡單,刪除結點有點複雜,但跟著演算法導論上一步一步來沒有什麼問題。不想備份blog的,所以沒有把上穿。可直接察看ppt。

紅黑樹性質

1.每個節點或是紅的,或是黑的

2.根節點是黑的

3.每個葉結點(nil)都是黑的

4.如果乙個結點是紅的,則它的兩個兒子都是黑的

5.對每個結點,從該節點到其子孫結點的所有路徑上包含相同數目的黑結點

*從某個結點x出發(不包括該結點)到達乙個葉結點的任意一條路徑上,黑色結點的個數成為該結點x的黑高度,用bh(x)表示。

*引理:一顆有n個內節點的紅黑樹的高度之多為2lg(n+1)

插入不變式

a)結點z是紅色。

b)如果p[z]是根,則p[z]是黑色。

c)如果有紅黑樹的性質被破壞,則至多只有乙個被破壞,並且不是性質2)就是性質4)。如果違反性質2),則發生的原因是z是根而且是紅的。如果違反性質4),則原因是z和p[z]都是紅色的,則p[p[z]]必然是黑色的。

針對違反性質4)

①z的叔叔y是紅色的

②z的叔叔y是黑色的,而且z是右孩子

③z的叔叔y是黑色的,而且z是左孩子

z的叔叔y是黑色的。這兩種情況是通過z是p[z]的左孩子還是右孩子來區別。在情況2中,結點z是他的父親的右孩子。我們立即使用乙個左旋來將此情況轉變為情況3,此時結點z成為左孩子。因為z和p[z]都是紅色的,所以所做的旋轉對結點的黑高度和性質5)都無影響。在情況3中,要改變某些結點的顏色,並作一次右旋以保持性質5。這樣,由於在一行中不在有兩個連續的紅色結點,因而,所有的處理完畢,無需再次執行while迴圈。

二叉查詢樹刪除

*二叉查詢樹刪除(刪除結點z)

如果z沒有子女,則修改其父結點p[z],使nil為其子女;

如果結點z只有乙個子女,則可以通過在其子結點與父結點間建立一條鏈來刪除z;

如果結點z有兩個子女,先刪除z的後繼y,再用y的內容替代z的內容。

*後繼二叉樹中,如果所有的關鍵字均不相同,則某一結點x的後繼既具有大於key[x]中的關鍵字中最小者的那個結點。

紅黑樹刪除

rb-delete(t,z)

1 if left[z] = nil[t] or right[z] = nil[t]

2 then y ← z

3 else y ← tree-successor(z)

4 if left[y] ≠ nil[t]

5 then x ← left[y]

6 else x ← right[y]

7 p[x] ← p[y]

8 if p[y] = nil[t]

9 then root[t] ← x

10 else if y = left[p[y]]

11 then left[p[y]] ← x

12 else right[p[y]] ← x

13 if y ≠ z

14 then key[z] ← key[y]

15 copy y』s satellite data into z

16 if color[y] = black

17 then rb-delete-fixup(t, x)

18 return y

a.如果被刪除的結點是紅色的,則當結點被刪除後,紅黑性質仍然得以保持,理由如下:

a)樹中各結點的黑高度都沒有變化

b)不存在兩個相鄰的紅色結點

c)因為如果該節點是紅的,就不可能是根,所以跟仍然是黑色的

b.如果被刪除的結點是黑色的,則會產生三個問題。

要刪除的結點y,如果y有個不是nil的孩子,則x為y的唯一孩子;如果y沒有孩子,則x為nil,把x的父節點(原來是y)賦值為y的父節點

①如果y原來是根結點,而y的乙個紅色的孩子成為了新的根,這就違反了性質2)。

②如果x和p[y](現在也是p[x])都是紅的,就違反了性質4)。

③刪除y將導致先前包含y的任何路徑上黑結點個數少1。因此,性質5)被y的乙個祖先破壞了。補救這個問題的乙個辦法就是把結點x視為還有額外的一重黑色。也就是說,如果將任意包含結點x的路徑上黑結點的個數加1,則這種假設下,性質5)成立。當將黑節點y刪除時,將其黑色「下推」至其子節點。現在問題就變為結點x可能既不是紅,也不是黑,從而違反了性質1)。結點x是雙重黑色或紅黑,這就分別給包含x的路徑上黑結點的貢獻2個或1個。x的color屬性仍然是red(如果x是紅黑的)或者black(如果x是雙重黑色)。換言之,乙個結點額外的黑色反映在x指向它,而不是他的color屬性。

刪除演算法

rb-delete-fixup(t, x)

1 while x ≠ root[t] and color[x] = black

2 do if x = left[p[x]]

3 then w ← right[p[x]]

4 if color[w] = red

5 then color[w] ← black case1

6 color[p[x]] = red case1

7 left-rotate(t,p[x]) case1

8 w ← right[p[x]] case1

9 if color[right[w]] = black and color[right[w]= black

10 then color[w] ← red case2

11 x ← p[x] case2

12 else if color[right[w]] = black

13 then color[left[w]] ← black case3

14 color[w] ← red case3

15 right-rotate(t,w) case3

16 w ← right[p[x]] case3

17 color[w] ← color[p[x]] case4

18 color[p[x]] ← black case4

19 color[right[w]] ← black case4

20 left-rotate(t,p[x]) case4

21 x ← root[t] case4

22 else (same as then clause with 「right」 and 「left」 exchanged)

23 color[x] ← black

第1-22行中while迴圈的目的是將額外的黑色沿樹上移,直到:

1.x指向乙個紅黑結點,將x(單獨)著為黑色。

2.x指向根,這時可以簡單地消除那個額外的黑色,或者

3.作必要的旋轉和顏色修改

紅黑樹(演算法導論)

測試 所用的例子為算導第三版p179圖13 4 include using namespace std const bool black 0 黑色 const bool red 1 紅色 struct node 結點結構 class rb tree 初始化nil結點和root node left r...

演算法導論例程 紅黑樹

紅黑樹是比較重要的資料結構,作為乙個典型的平衡二叉樹 沒有一條簡單路徑是其他路徑的二倍 它與二叉搜尋樹的區別是它的結點多了乙個屬性 color,color有兩種值,red和black,顏色的選取遵循以下原則 1 每個節點是紅色的,或是黑色的 2 根節點是黑色的 鬆弛紅黑樹 relaxed red b...

演算法導論學習筆記 紅黑樹

紅黑樹的5個性質 1 每個結點要麼是紅的,要麼是黑的。2 根結點是黑的。3 每個葉結點,即空結點 nil 是黑的。4 如果乙個結點是紅的,那麼它的倆個兒子都是黑的。5 對每個結點,從該結點到其子孫結點的所有路徑上包含相同數目的黑結點。public class rbtree 當在某個結點nodex上,...