紅黑樹的刪除

查閱了很多的資料,最終把紅黑樹的刪除操作弄明白。爲方便日後溫習,也爲那些正想弄明白但又苦苦明白不了該操作詳細原理的同學查閱,特將其當筆記記錄下來。下面內容是個人所理解的紅黑樹的刪除操作,如果有不對的地方,歡迎各路大神指正。

 

紅黑樹的刪除操作

 

1:節點命名約定

    D表示要被刪除的節點。即:取 Delete 的首字母;

    P 表示父節點。即:取 Parent 的首字母;

    S表示兄弟姐妹節點。即:取 Sibling的首字母;

    U表示叔伯節點。即:取Uncle的首字母;

    G表示祖父節點。即:取 Grandfather的首字母;

    L表示左樹。即:取Left的首字母;

    R表示右樹。即:取Right的首字母;

    Nil表示葉子節點。即所謂的空節點;注意:紅黑樹中的葉子節點與其他樹中所述說的葉子節點不是同一概念。而且紅黑樹中的葉子節點(即:Nil節點)永遠是被定義爲黑色的。

 

    下文的節點命名錶示將會使用以上這些命名約定或它們的組合表示。因此,請先牢記這些命名約定。舉例:

    DR表示要被刪除的節點的右子樹,即:右子節點;

    SL表示兄弟節點的左子樹,即:左子節點;

    …

 

2:刪除操作宏觀分析

    在紅黑樹中,刪除一個節點往大的說,只有以下四種情況。

    情況一:刪除的節點的左、右子樹都非空;

    情況二:刪除的節點的左子樹爲空樹,右子樹非空;

    情況三:刪除的節點的右子樹爲空樹,左子樹非空;

    情況四:刪除的節點的左、右子樹都爲空樹;

    其中情況一,可以按與其他二叉搜索樹的刪除方式一樣處理,最終可以轉換到後面的三種情況。具體爲:找到(Old)D節點的直接後繼節點(暫且稱爲X節點),然後將X的值轉移到D節點,最後將X節點作爲真正要被刪除掉的節點(即:(Real)D節點)。這樣刪除操作後,可以保證該樹仍然爲一棵二叉搜索樹。但由於紅黑樹的定義(即:紅黑樹的性質)約定。這樣刪除(Real)D節點後,可能會破壞紅黑樹的性質。所以需要額外做一些調整處理,這便是下面將要詳細討論的內容。

    說明:下文中所提到的D,除非有特別說明,否則都將指的是(Real)D。

 

3:紅黑樹刪除後平衡處理

    在具體分析之前,再次列出紅黑樹的定義:

    1)       任何一個節點非紅即黑;

    2)       樹的根爲黑色;

    3)       葉子節點爲黑色(注意:紅黑樹的所有葉子節點都指的是Nil節點);

    4)       任何兩個父子節點不可能同時爲紅色;

    5)       任何節點到其所有分枝葉子的簡單路徑上的黑節點個數相同;

 

    下面是幾個圖示說明:

    根據紅黑樹的定義,被刪除的節點D(即:上文所述的(Real)D節點)不論如何都一定有一個“右子樹”,只是該右子樹要不爲非空樹(即:真正存在的節點,不爲Nil節點),要不就必爲空樹(即:D的兩個子節點都爲Nil)。下面稱D的該右子節點(或稱爲右子樹)爲DR。

    a)       被刪除的D節點爲紅色。這種情況,則與D相關的顏色以及結構關係必然只有如下一種情況(爲什麼只有這種情況,不明白的請看紅黑樹的性質):

    分析:因爲D爲紅色,所以P必爲黑色,同時DR不可能爲紅色(否則違反性質4)。同時由於性質5,則DR必爲Nil,否則就D樹來說,經過DR與不經過DR的路徑的黑節點數必不相同。現在要刪除D節點,只需要直接將D節點刪除,並將DR作爲P的左子節點即可。因此刪除後,變成上圖右側所示。

 

    b)       被刪除的D節點爲黑色。此時情況會稍複雜些,具體又分析爲:DR爲Nil與DR不爲Nil。根據性質5,如果DR不爲Nil,則DR必爲紅色,且DR的兩個子節點必爲Nil。因此,此處先來分析DR不爲Nil的情況(因爲該情況比較簡單)。而DR爲Nil的情況,由後面的C)及其後內容再進行具體分析 。

如前所述,如果DR不爲Nil,則D、DR必爲如下情況:

    分析:由於刪除的D爲黑色,刪除後P的左子樹的黑節點數必少1,此時剛好DR爲黑色,並且刪除後DR可以佔據D的位置(這樣仍是一棵二叉搜索樹,只是暫時還不是合格的紅黑樹罷了),然後再將DR的顏色改爲黑色,剛好可以填補P左子樹所減少的黑節點數。從而P樹又平衡了。因此,平衡處理後,最終變成上圖右側的圖示。

    c)       被刪除的D爲黑色,且DR爲Nil

如果DR爲Nil,則刪除D後,P的左子樹黑節點數必定少1,純粹想在P的左子樹做文章來平衡P樹是絕無可能的了。因此,必定需要其他分支的輔助來最終完成平衡調整。根據紅黑樹的定義,P會有一個右子節點,稱爲S子節點。此處又可細節分兩種情況:黑S與紅S。此處先討論紅S的情況。

    說明:如果S爲黑,則它必不會爲Nil。(不明白的人,再好好想想爲什麼)。同時根據紅黑樹的性質,D、S、P、SL、SL的顏色關係必只有如下一種情況(因爲此處探討的是S爲紅的情況)。

    分析:刪除前P樹的左、右子樹的黑節點數平衡,刪除後(即:上圖右側所示),經過DR分支的黑節點數將比通過S分支的黑節點數少1。此時,做如下操作:

    將P左旋轉,再將P由黑色改爲紅色,將S由紅色改爲黑色,演變過程如下圖示:

    經過以上演變後,經過P的路徑,左分支黑節點數仍是少1,其他分支的黑節點數做仍然保持不變。此時的情況卻變成DR的兄弟節點爲黑色(不再是紅色的情況了),因此轉入此處c)點一開始所說的另一種情況(S爲黑色的情況)的處理。

    注意:可能有人會一時想不明白什麼要這樣轉換。因爲這樣轉換後,雖然對於P樹的左子樹的黑節點數仍然會比右子樹的黑節點數少1,但此時DR的兄弟(以前的S節點)現在已經變爲SL,即已經由紅色變爲黑色,並且非常重要的此時的DR的兄弟節點SL的子結點(即:DR的兩個侄子節點),要不就是紅色節點要不就必爲Nil節點,而這種情況正是D爲黑色、S也黑色的情況。(注意看注意看注意看一定注意看這點:對於被刪除節點D的父節點來說,D黑S黑的情況下,無論如何D的兄弟節點S的兩個兒子節點SL與SR都不可能是非Nil的黑節點。不明白的好好想想爲什麼)。因此我們有了進一步分析的餘地。

    d)       被刪除的D爲黑色,S也爲黑色的情況。根據D、P、S、SL、SR的顏色組合情況,本來是有非常多種變換的。但事實上,我們只需要按如下4種情況做進一步的處理,即可全部涵蓋所有的顏色組合情況。

    d.1> SL爲紅,SR顏色任意;(對於該情況的處理,其實我們不關心P的顏色)

    d.2> SR爲紅,SL顏色任意;(對於該情況的處理,其實我們不關心P的顏色)

    d.3> SL、SR都爲黑;P爲紅。(注意:根據前面c)點的紅色文字部分的分析,此時SL與SR必定必定都爲Nil節點);

    d.4> SL、SR都爲黑;P爲黑。(注意:根據前面c)點的紅色文字部分的分析,此時SL與SR必定必定都爲Nil節點);

 

    d.1> SL爲紅,SR顏色任意情況

    分析:P樹的左子樹黑節點數減少1,因此,要想平衡,必需想辦法讓左子樹的黑結節數增加1,而且同時P的右子樹的黑節點數要保持不變。因此,想辦法將SL這個紅色節點利用起來,讓它來填補P的左子樹所缺少的黑節點個數。因此,立馬想到旋轉,只要有辦法轉到P的左子樹或P位置上,則就有可能填平P左子樹的高度。所以具體操作步驟爲:

    將S右旋轉;接着將SL改爲P的顏色,P的顏色改爲黑色(用這個黑色來填補DR分支的黑節點數);將P左旋轉。

 

    d.2> SR爲紅色,SL顏色任意的情況

    分析:思路同d.1>情況類似,都是想辦法用紅色的SR節點來填補P的左子樹的減少的黑節點數。具體步驟爲:

    將S由黑色改爲P的顏色;

    將SR由紅色改爲黑色;

    將P的顏色改爲黑色(用該黑色來填補DR分支缺失的黑節點數);

    將P節點左旋轉;

 

    d.3> SL、SR都爲黑色(其實都爲Nil節點),P爲紅色的情況

    分析:此情況較爲簡單,直接將紅色的P改爲黑色,以此爲填補DR缺少的黑節點個數。此時P右子樹黑節點數卻增多,因此,再將S改爲紅色即可平衡。

 

    d.4> SL、SR都爲黑色(其實都爲Nil節點),P爲黑色的情況

    分析:因爲DR、P、S、SL、SR全都爲黑色,則不論如何變換,都永遠不可能使用P的左右子樹的黑節點數達到平衡。而P不平衡的原因是因爲P的右子樹黑節點數會比左子樹多1個。因此,乾脆將S由黑色改爲紅色,如此一來,P的左、右子樹的黑節點個數是平衡的。但是,此時經過P的路徑的黑節點個數將會比不經過它的路徑少一個。因此,我們將P作爲待平衡的節點(即:此時的P相當於DR的角色)往上繼續上溯,直到P爲根節點爲止。

 

    到此,紅黑樹的刪除操作已全部說明完。從以上的分析來看,紅黑樹的刪除操作將是最爲費時的,至少會比插入操作複雜,更耗時的可能性肯定會更大。但事實上,紅黑樹的插入、刪除、效率都是非常高的。插入比較簡單就不說了。刪除操作事實上,就算遇到最壞情況:DR、P、S、SL、SR全爲黑的情況下,在上溯過程中,一般情況下也是會很快就遇到紅色的P節點的。除非整棵紅黑樹的右子樹基本上都是黑節點(試想下,這可能性幾乎不可能,因爲我們插入時,總是以紅色插入的,再加上紅黑樹的幾條性質約束一下),或者本來身紅黑樹的整體高度就非常淺。

 

    以上是個人的理解,歡迎指正。

摘自:https://www.cnblogs.com/tongy0/p/5460623.html

 

感覺這篇文章寫的很好,我就有一點感受。那就是每個刪除,都有一個思路,那就是通過對紅色的節點進行轉變。

因爲,紅黑樹中,紅色節點是可以邊爲黑色節點的,除了對黑高有影響,其他性質是不會影響的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章