紅黑樹 3 刪除操作

2021-09-08 04:01:35 字數 4412 閱讀 8612

在本系列的前面兩篇文章中。已經介紹了紅黑樹以及其插入操作。

紅黑樹(2) - 插入操作

類似於插入操作。紅黑樹進行刪除節點時,也使用又一次著色以及旋轉這兩種方式。來維護它的屬性。在插入操作中,我們主要是依靠檢測叔節點的顏色來決定哪種場景。在刪除操作中,我們使用檢測兄弟的顏色,來決定是哪種場景。

在插入操作中,最常見的違反紅黑樹屬性的一種情況是存在兩個連續的紅色節點。

而在刪除操作中。常見的情況是,當刪除節點是黑色時,會影響從根節點到葉子的黑色節點高度。違反紅黑樹的性質5。

刪除的過程相對照較複雜。為了便於理解刪除過程,我們將使用到"double black"的概念。當乙個黑色節點被刪除,而且被它的黑色孩子代替時,這個孩子就標記為double black。因此,基本的工作就變為了將這個double black轉換為single black。

以下是具體的刪除步驟。

在以下的內容裡。d表示被刪節點。c表示將用於替換d的孩子節點

執行標準的二叉搜尋樹的刪除操作。在刪除過程中,假設d是葉子或者僅僅有乙個孩子。則操作比較簡單,基本上直接刪除就能夠了。而對於存在兩個孩子的節點,能夠先查找到d的中序遍歷時的後繼節點。用它的值替換掉d的值,然後再刪除這個後繼節點(中序遍歷時的興許節點總是乙個葉子或僅僅有乙個孩子)。

例如以下圖所看到的。這種話。我們僅僅須要處理被刪節點是葉子或僅僅有乙個孩子的這種情況。

50                                            60                                        60

/ \ delete(50) / \ delete(60') / \

40 70 -----------------> 40 70 ------------------> 40 70

/ \ 後繼節點賦值 / \ 刪除後繼節點 \

60 80 給被刪節點 60' 80 80

上圖中,被刪節點d是50,則它的中序遍歷後繼節點是60。用後繼節點的值替換d的值,然後刪除60這個後繼節點。

當然,在本步驟中,也能夠選取前驅節點(即被刪節點左子樹最大值)進行替換。

原理與後繼節點相似。這裡不再描寫敘述。

使用孩子節點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

/ \ delete(10) / \

10 40 -------------> 20 40

\

20

對於d擁有兩個孩子(兩顆子樹)的場景。如以下的兩個圖所看到的。能夠採用第2節提供的方法。轉換為處理葉子節點或單個孩子的場景。

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

/ \ delete(20) / \ delete(30') / \

20 50 ----------------------> 30 50 ---------------------> 30 50

/ \ 執行步驟2.1,將d的 / \ 此時轉換為了刪除葉子30'. /

1030

後繼節點的值賦給d.

1030'

10

此時,主要工作就是將這個double black轉換為single black。注意:當d是葉子時,則預設c為null節點而且為黑色。

所以,假設刪除的是黑色葉子,則也會引發double black操作。

上圖中,在轉換為了double black後,實際上已經變成了4.2.1.c的場景。能夠使用right right case旋轉方式。

終於,刪除節點20後,這棵樹調整為:

30                            40

/ \ delete(20) / \

20 40 -------------> 30 50

\

50

在這樣的情況下,如果s表示d的兄弟節點,則存在以下這些場景。

如果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 被刪結點無子...