1. 程式人生 > >資料結構——紅黑樹的刪除節點操作

資料結構——紅黑樹的刪除節點操作

1. 紅黑樹的刪除操作過程分析

    1. 首先看一下普通搜尋二叉樹的刪除操作,普通搜尋二叉樹刪除結點找替代結點有3種情情景:

  • 情景1:刪除結點無子結點,直接刪除
  • 情景2:刪除結點只有一個子結點
  • 情景3:刪除結點有兩個子結點

在這裡有一個重要的思路:刪除結點被替代後,在不考慮結點的鍵值的情況下,對於樹來說,可以認為刪除的是替代結點。

基於此,上面所說的3種二叉樹的刪除情景可以相互轉換並且最終都是轉換為情景1。

  • 對於情景2:刪除結點用其唯一的子結點替換,子結點替換為刪除結點後,直接刪除
  • 對於情景3:刪除結點用其子樹中大於該節點的最小節點(該節點一定不存在左子節點)進行替換,如果替換節點有右子結點,那麼相當於轉換為情景2,否則轉為為情景1。

所以,刪除操作刪除的結點可以看作刪除替代結點,而替代結點最後總是在樹末(找到的替代節點一定是樹末節點,樹末節點指的是子節點有一個為NIL的節點),紅黑樹也一樣。

    2. 紅黑樹中刪除節點時可能的情景:與普通搜尋二叉樹中刪除節點不同,每當刪除一個紅黑樹節點,就必須對紅黑樹進行平衡,但是刪除紅色樹末節點一定是不影響平衡的。要明確一點,找到的替代節點一定是樹末節點,也就是替代節點的左子節點一定為NIL節點,或左右子節點全為NIL節點。可能情景如下

(1)替換節點是紅色的:替換節點是紅色的,刪除後不影響紅黑樹平衡,所以直接替換刪除即可。

(2)替換節點是黑色的,但其有一個子節點,該節點是紅色右子節點,右子節點也不可能是黑色(不可能是紅色左子節點)

:將右子節點改為黑色,再用右子節點頂替替換節點即可。

——>

(3)替換節點是黑色的,無子節點,而且是其父節點的左子節點,而且替換節點的兄弟節點是紅色的:替換節點的兄弟節點是紅色那麼父節點一定是黑色,兄弟節點一定具有左右黑色子節點,而且是最底層節點。此時所需要做的就是將情景轉化為情景1,思考一下如何在保證這部分子樹紅黑樹性質的情況下,將R節點(替換節點)轉化為紅色節點。其實很簡單,首先將S與P節點進行顏色互換,然後將S與P節點進行左旋操作,如下圖所示;轉換完成後,是否可以直接將P節點換為黑色節點,R與SL換為紅色呢?這樣就可以直接刪除R節點了,如果SL節點無子節點那確實可以,但如果有子節點,那一定是紅色子節點,如果SL節點換為紅色就會違反紅黑樹性質。那麼這種情況該如何處理呢?這時的情況就跳轉到了情況4進行解決

——>——>

(4)替換節點是黑色,無子節點,而且是其紅色父節點的左子節點,而且替換節點的兄弟節點是黑色的(兄弟節點下一定只有0-2個紅色子節點):先直接將P節點與S節點進行一次左旋操作,保持節點顏色不變; 然後就可以直接刪除替換節點R了; 如果S節點有紅色左子節點,就很熟悉了,這正是紅黑樹的節點插入場景,將SL節點作為插入節點看待,進行一次插入操作的平衡即可。而其有沒有紅色右子節點就無所謂了。如下圖所示

——>——>

(5)替換節點R是黑色,無子節點,而且是其黑色父節點的左子節點,而且替換節點的兄弟節點是黑色的(兄弟節點下一定只有0-2個紅色子節點):

如果兄弟節點含有左子節點或右子節點都還簡單,如果只要通過變換保證S節點位置的節點有右子節點(如果只有左子節點SL,就將SL與S節點進行顏色互換,然後右旋,將S變為SL的右子節點即可;如果S節點本身就有右子節點就不需要變換了),然後對兄弟節點和父節點進行左旋處理,再對SR節點改為黑色就可以刪除R節點了,如下圖所示

對S節點和P節點左旋操作——>改色,刪除R節點——>

將S和SL節點換色,然後右旋——>再對SL節點和P節點左旋操作並將S節點改為黑色即可刪除R節點

(6)替換節點R是黑色,無子節點,而且是其黑色父節點的左子節點,而且替換節點的兄弟節點是黑色的,且都無子節點:此時對這三個節點無論怎樣變換都無法在刪除R節點後讓樹平衡,所以此時需要向上探索保持平衡,也就是將P節點視作R節點向上平衡(所謂將P節點視作R節點也就是將不在乎P節點的左右子節點,就當做這是要被替換刪除的一個樹末節點,然後向上重新平衡),但並不是要刪除P節點,而是通過一層層向上調整來重新讓樹達到平衡,達到平衡後在刪除R節點

2. 具體實現程式碼

(待新增)