1. 程式人生 > >紅黑樹之刪除操作

紅黑樹之刪除操作


現在我們來看紅黑性質的恢復過程:
      如果Y指向的節點是個紅色節點,那麼直接刪除掉Y以後,紅黑性質不會被破壞。操作結束。
      如果Y指向的節點是個黑色節點,那麼就有幾條紅黑性質可能受到破壞了。首先是包含Y節點的所有路徑,黑高度都減少了一(第5條被破壞)。其次,如果Y的有紅色子節點,Y又有紅色的父節點,那麼Y被刪除後,就出現了兩個相鄰的紅色節點(第4條被破壞)。最後,如果Y指向的是根節點,而Y的子節點又是紅色的,那麼Y被刪除後,根節點就變成紅色的了(第2條被破壞)。
      其中,第5條被破壞是讓我們比較難受的。因為這影響到了全域性。這樣動作就太大太複雜了。而且在這個條件下,進行其它紅黑性質的恢復也很困難。所以我們首先解決這個問題:如果不改變含Y路徑的黑高度,那麼樹的其它部分的黑高度就必須做出相應的變化來適應它。所以,我們想辦法恢復原來含Y節點的路徑的黑高度。做法就是:無條件的把Y節點的黑色,推到它的子節點X上去
。(X可能是NIL節點)。這樣,X就可能具有雙重黑色,或同時具有紅黑兩色,也就是第1條性質被破壞了。
      但第1條性質是比較容易恢復的:一、如果X是同時具有紅黑兩色,那麼好辦,直接把X塗成黑色,就行了。而且這樣把所有問題都解決了。因為將X變為黑色,2、4兩條如果有問題的話也會得到恢復,演算法結束。二、如果X是雙黑色,那麼我們希望把這種情況向上推一直推到根節點(調整樹結構和顏色,X的指向新的雙黑色節點,X不斷向上移動),讓根節點具雙黑色,這時,直接把X的一層黑色去掉就行了(因為根節點被包含在所有的路徑上,所以這樣做所有路徑同時黑高減少一,不會破壞紅黑特徵)。
      下面就具體地分析如何恢復1、2、4三個可能被破壞的紅黑特性:我們知道,如果X指向的節點是有紅黑兩色,或是X是根節點時,只需要簡單的對X進行一些改變就行了。要對除X節點外的其它節點進行操作時,必定是這樣的情況:X節點是雙層黑色,且X有父節點P。由知可知,X必然有兄弟節點W,而且這個W節點必定有兩個子節點。(因為這是原樹滿足紅黑條件要求而自然具備的。X為雙黑色,那麼P的另一個子節點以下一定要有至少兩層的節點,否則黑色高度不可能和X路徑一致)。所以我們就分析這些節點之間如何變形,把問題限制在比較小的範圍內解決。另一個前提是:X在一開始,肯定是樹底的葉節點或是NIL節點,所以在遞歸向上的過程中,每一步都保證下一步進行時,至少 X的子樹是滿足紅黑特性的。因此子樹的情況就可以認為是已經正確的了,這樣,分析就只限制在X節點,X的父節點P和X的兄弟節點W,以及W的兩個子節點中。
      下面僅僅考慮X原本是黑色的情況即可。
      在這種情況下,X此時應該具有雙重黑色,演算法的過程就是將這多出的一重黑色向上移動,直到遇到紅節點或者根節點。
      接著往下分析, 會遇到4種情況,實際上是8種, 因為其中4種是相互對稱的,這可以通過判斷X是其父節點的右孩子還是左孩子來區分。下面我們以X是其父節點的左孩子的情況來分析這4種情況,實際上接下來的調整過程,就是要想方設法將經過X的所有路徑上的黑色節點個數增加1。
      具體分為以下四種情況:(下面針對x是左兒子的情況討論,右兒子對稱)
     Case1:X的兄弟W是紅色(想辦法將其變為黑色)
       由於W是紅色的,因此其兒子節點和父節點必為黑色,只要將W和其父節點的顏色對換,在對
父節點進行一次左旋轉,便將W的左子節點放到了X的兄弟節點上,X的兄弟節點變成了黑色,且紅黑性質不變。但還不算完,只是暫時將情況1轉變成了下面的情況2或3或4。