紅黑樹——自平衡過程


紅黑樹的概念,這里不做闡述。網上一抓一大把。本文僅以個人的理解介紹一下紅黑樹自平衡的過程。

紅黑樹的性質:

  • 性質1:每個節點要么是黑色,要么是紅色。
  • 性質2:根節點是黑色。
  • 性質3:每個葉子節點(NIL)是黑色。
  • 性質4:每個紅色結點的兩個子結點一定都是黑色。
  • 性質5:任意一結點到每個葉子結點的路徑都包含數量相同的黑

自平衡所需要的操作,無非是變色,左旋,右旋。變色不用多說,黑變紅紅變黑。關於左旋,先附上網上找到的一個圖

 

圖片來源:http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml

由於紅黑樹本身是一棵二叉搜索樹,即左子樹的所有節點值都小於自己,右子樹的所有節點值都大於自己。於是,在旋轉過程,把y提為本子樹的根節點時,由於y原來是x的右孩子,y > x,x成為y的左孩子。y原本的左孩子b就得給x騰出位置,x的右節點恰好空了出來。b原為x的右子樹成員,b > x,成為x的右孩子很合理。

關於右旋,原理相同。

 

圖片來源:http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml

 

現在開始說明紅黑樹的自平衡。

首先是插入節點的着色。所有關於紅黑樹自平衡的介紹都說,插入的節點為紅色。至於為什么,筆者認為,由於性質3與性質5,任意一結點到每個葉子結點的路徑都包含數量相同的黑,且每個葉子節點(NIL)是黑色。新插入的節點初始位置必為替換某個葉子節點,同時自己又會新產生左右兩個葉子節點。若新插入的節點為黑,則將會引起從根節點到新節點的路徑上黑色節點數量比其它路徑多了1。而插入紅色節點,則不會有此情況,但是有可能會違反性質4,每個紅色結點的兩個子結點一定都是黑色,出現連續的兩個紅色節點,但是不是必然發生。所以新插入的節點為紅色,可以使得需要自平衡操作的幾率降低。

然后,若真的出現了連續兩個紅色節點的情況,不影響整體黑高的情況下的調整,能大大降低調整次數。

在新插入一個紅節點時,除了當前是空樹外可能的情況有:

1、其父節點為黑色。這種情況不會改變其父節點處的黑高,也不會打破任何性質。不用做任何處理

2、其父親節點為紅色。由於紅黑樹是自平衡的,在新插入一個節點之前,它已經是平衡的,滿足所有性質。故其祖父節點一定為黑色。

a.其叔叔節點為葉子節點。若為在根節點的右孩子的左子樹上插入新節點(RL)。單純修改其父節點顏色並不能使其平衡。

 

 若直接對20,10進行左旋,則得到

 

 又用相同方式左旋,將又會得到初始狀態,死循環。若先對15,20進行右旋,則將會得到RR:

此時再對10,15進行左旋,將會得到:

 

 然后再對10,15進行變色

 

 

 此時達到平衡。LR的情況與之相同,操作方式相反,不再單獨敘述。而RR的情況上面已經描述,LL與RR情況相同,操作相同,亦不做描述。

b.其叔叔節點為紅節點

 

 此時直接同時把父節點與叔叔節點進行變色

 

 而此時將會導致祖父節點15的黑高+1。因不確定其是否還有父節點,為了不必要的麻煩,將15設置為紅色,即可保持15的黑高不變。  

 

 說明:此處僅以15做為某樹的子樹的根節點,並非打破性質2。

c.其叔叔節點為黑色節點(非葉子)此情況在剛插入時並不存在。理由如下:每條路徑的黑色節點數量必須相同。若新插入的節點的父節點是紅色,而叔叔節點是黑色,則只能說明叔叔節點的黑高比父節點的多1。

 

現以一個簡單的實例:

向一棵紅黑樹順序插入數字1,2,3,4,5

首先,插入1,紅節點。

 

根據性質2,根節點是黑色,直接換成黑色即可。此時黑高為2

 

 

然后插入2。並未打破5大性質,不用做任何處理。此時所有路徑的黑高為2。

 

 

插入3之后(RR)

 

 

對3的父親節點2與祖父節點進行左旋,然后變色

 

 

 

 然后繼續插入4

 

此時再次出現相鄰紅色節點。4的父親節點3與叔叔節點1均為紅色,此時將二者都進行變色操作,一可保持性質4,二不會改變黑色節點之差。

 

 

 此操作之后,4的祖父節點2的黑高+1。若其為某紅黑樹的某子樹,則會破壞平衡。故將其進行變色處理。

 

 

然后繼續以2為基礎做自平衡。發現其已經是根節點,沒有父節點,自己的子樹已達到平衡,不用繼續處理。然后根據性質2,將其設置為黑色。此時黑高為3。

 

繼續插入5

 

   再次出現相鄰紅色節點,情況與插入3時相同,做相同處理

 

 現分析下列紅黑樹插入節點21的情況。插入之前,根節點的黑高為3。

 

 

圖片來源:http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml

說明:前幾步與來源講解的有點類似,最后並不像來源處將13 17左旋了。

 

 節點21 22為相鄰紅色節點,要對新插入的節點21的父節點22進行變色。21的叔叔節點27同為紅色,與22同時變色,可保證21的祖父節點25保持平衡。

 

 

 

而此操作之后,將會導致25子樹黑高+1,使得其黑高比其兄弟節點多1。為了防止這種情況,25需要跟着色,才能保證25節點子樹的黑高不變,從而不影響整個紅黑樹的黑高。

 

 雖然整體黑高沒有發生變化,但是再次出現了相鄰紅色節點17 25。用相同策略,把8,17,13同時進行變色。

 

此時13節點的左右子樹的黑高均是3,保持平衡。且13為根節點,沒有父節點,13的平衡代表整個紅黑樹的平衡,不用再繼續處理。  然后根據性質2,將根節點13改為黑色。

 

 

 若此時再插入節點20,則

由於20的叔叔節點為黑色節點,單純修改父節點為黑色,只會導致祖父節點變得不平衡。旋轉21,22,並各自變色,就可以達成平衡

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM