在本系列的前面兩篇文章中。已經介紹了紅黑樹以及其插入操作。
紅黑樹(2) - 插入操作
類似於插入操作。紅黑樹進行刪除節點時,也使用又一次著色以及旋轉這兩種方式。來維護它的屬性。在插入操作中,我們主要是依靠檢測叔節點的顏色來決定哪種場景。在刪除操作中,我們使用檢測兄弟的顏色,來決定是哪種場景。
在插入操作中,最常見的違反紅黑樹屬性的一種情況是存在兩個連續的紅色節點。
而在刪除操作中。常見的情況是,當刪除節點是黑色時,會影響從根節點到葉子的黑色節點高度。違反紅黑樹的性質5。
刪除的過程相對照較複雜。為了便於理解刪除過程,我們將使用到"double black"的概念。當乙個黑色節點被刪除,而且被它的黑色孩子代替時,這個孩子就標記為double black。因此,基本的工作就變為了將這個double black轉換為single black。
以下是具體的刪除步驟。
在以下的內容裡。d表示被刪節點。c表示將用於替換d的孩子節點。
執行標準的二叉搜尋樹的刪除操作。在刪除過程中,假設d是葉子或者僅僅有乙個孩子。則操作比較簡單,基本上直接刪除就能夠了。而對於存在兩個孩子的節點,能夠先查找到d的中序遍歷時的後繼節點。用它的值替換掉d的值,然後再刪除這個後繼節點(中序遍歷時的興許節點總是乙個葉子或僅僅有乙個孩子)。
例如以下圖所看到的。這種話。我們僅僅須要處理被刪節點是葉子或僅僅有乙個孩子的這種情況。
50 60 60上圖中,被刪節點d是50,則它的中序遍歷後繼節點是60。用後繼節點的值替換d的值,然後刪除60這個後繼節點。/ \ delete(50) / \ delete(60') / \
40 70 -----------------> 40 70 ------------------> 40 70
/ \ 後繼節點賦值 / \ 刪除後繼節點 \
60 80 給被刪節點 60' 80 80
當然,在本步驟中,也能夠選取前驅節點(即被刪節點左子樹最大值)進行替換。
原理與後繼節點相似。這裡不再描寫敘述。
使用孩子節點c替換d。然後將其置為黑色。這樣黑色高度維持不變。這是由於d和c不可能同一時候是紅色。當中必然有乙個為黑色。
本步驟會覆蓋到以下的這4種場景。
30 30/ \ delete(20) / \
20 40 -------------> 10 40
/
10
30 30/ \ delete(10) / \
10 40 -------------> 20 40
\
20
30 30/ \ delete(20) / \
20 40 -------------> 10 40
/
10
30 30對於d擁有兩個孩子(兩顆子樹)的場景。如以下的兩個圖所看到的。能夠採用第2節提供的方法。轉換為處理葉子節點或單個孩子的場景。/ \ delete(10) / \
10 40 -------------> 20 40
\
20
40 40 40/ \ delete(20) / \ delete(30') / \
20 50 ----------------------> 30 50 ---------------------> 30 50
/ \ 執行步驟2.1,將d的 / \ 此時轉換為了刪除葉子30'. /
10 30 後繼節點的值賦給d.
10 30' 10
40 40 40此時,主要工作就是將這個double black轉換為single black。注意:當d是葉子時,則預設c為null節點而且為黑色。/ \ delete(20) / \ delete(30') / \
20 50 ----------------------> 30 50 ---------------------> 30 50
/ \ 執行步驟2.1,將d的 / \ 此時轉換為了刪除葉子30'. /
1030
後繼節點的值賦給d.
1030'
10
所以,假設刪除的是黑色葉子,則也會引發double black操作。
上圖中,在轉換為了double black後,實際上已經變成了4.2.1.c的場景。能夠使用right right case旋轉方式。
終於,刪除節點20後,這棵樹調整為:
30 40在這樣的情況下,如果s表示d的兄弟節點,則存在以下這些場景。/ \ delete(20) / \
20 40 -------------> 30 50
\
50
如果s的這個紅色的孩子為r,則依據s和r的位置,能夠分為4種情況。
a. left left case (s是左孩子,且r是s的左孩子或者s的兩個孩子都是紅色)。
這樣的情形與以下的right right case正好相反。
b. left right case (s是左孩子,且r是s的右孩子)。這樣的情形與以下的right left case正好相反。
c. right right case (s是右孩子,且r是s的右孩子或者s的兩個孩子都是紅色)。
d.right left case (s是右孩子,且r是s的左孩子)。
這樣的情況下
須要又一次著色。而且:
a. 假設s的父節點是黑色,則做完刪除操作後,還須要檢測父節點。
b. 假設s的父節點是紅色,則不須要再檢測父節點,而是能夠簡單地將其設定為黑色(紅色+double black = single black)。
此時新的兄弟節點總是黑色的(下圖的節點25)。至此,已經將這棵樹通過旋轉,轉換為了兄弟為黑色的這樣的場景。使用4.2.1或者4.2.2繼續處理。這樣的情形能夠分為兩種情況。
a. left case (s是左孩子)。右旋轉父節點p。
b. right case (s是右孩子). 左旋轉父節點p。
紅黑樹刪除操作
紅黑樹刪除操作 紅黑樹要刪除某個key值時,首先還是要查詢該key值在樹中的位置,查詢方法和搜尋二叉樹方法相同 要刪除的結點分為兩種情況 有左右兩個孩子都存在 兩個孩子都存在時,在該節點的右子樹中尋找其直接後繼,找到後用其值替換要刪除節點的值,然後問題轉化為刪除該節點的直接後繼,直接後繼是有乙個右孩...
紅黑樹學習筆記(3) 刪除操作
1 設刪除的節點為 z 另外定義節點 x,y 如下 y left z z的左孩子或右孩子為空節點 successor z otherwise end right.x left y.left y的左孩子不為空 y.right otherwise end right.其中 successor 函式的定義...
紅黑樹的刪除操作
原文 可能出現的情形討論 刪除紅黑樹中乙個結點,刪除的結點是其子結點狀態和顏色的組合。子結點的狀態有三種 無子結點 只有乙個子結點 有兩個子結點。顏色有紅色和黑色兩種。所以共會有6種組合。組合1 被刪結點無子結點,且被刪結點為紅色 此時直接將結點刪除即可,不破壞任何紅黑樹的性質。組合2 被刪結點無子...