二叉樹之紅黑樹的原理(一) 刪除

紅黑樹是一種特殊的排序二叉樹,在知足排序二叉樹的條件以後,還要知足如下幾個特色:spa

紅黑樹:      1 根結點是黑色.
                2 葉節點都是Nil結點,且爲黑色  
                3  父子節點不能同時爲紅色 
                4 從任意結點出發,到其每一個葉結點的路徑上都包含相同的黑結點數目. 
其中, 3,4 兩個特色是關鍵.3d

紅黑樹的刪除操做blog

 

1:節點命名約定排序

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

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

    S表示兄弟姐妹節點。即:取 Sibling的首字母; SL表示兄弟節點的左子樹,即:左子節點;二叉樹

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

    L表示左樹。即:取Left的首字母;
    R表示右樹。即:取Right的首字母;
    DR表示要被刪除的節點的右子樹,即:右子節點;  以此類推.方法

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

2:刪除操做宏觀分析

    在紅黑樹中,被刪除的結點,  只有如下四種狀況。

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

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

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

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

    其中狀況一,能夠按與普通二叉搜索樹的刪除方式同樣處理。具體方法爲:找到D節點的直接後繼節點(暫且稱爲X節點),而後將X的值轉移到D節點,最後將X節點做爲真正要被刪除掉的節點。
    查找直接後繼點X的方法是: 從D結點轉向右,再左轉,一直向左前進, 直到左分支的盡頭便是X點,  所以 X點是沒有左子樹的, 與狀況二或狀況四形同

    咱們獲得一條很是重要的結論:  紅黑樹中真正要刪除的結點,要麼只有單子樹,要麼是個無子樹的單結點.

    

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

      下面是幾個圖示說明:

    根據紅黑樹的定義,被刪除的節點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節點的。除非整棵紅黑樹的右子樹基本上都是黑節點(試想下,這可能性幾乎不可能,由於咱們插入時,老是以紅色插入的,再加上紅黑樹的幾條性質約束一下),或者原本身紅黑樹的總體高度就很是淺。

相關文章
相關標籤/搜索