二叉查找樹-紅黑樹


偶然抽了兩三個小時的空學了下紅黑樹,現在來整理一下。
紅黑樹,本質上還是一棵二叉查找樹,但是它卻有其神奇之處——查找、插入、刪除的時間複雜度最壞情況下爲O(log(n))。
如圖就是一顆紅黑樹(借用一下別人的圖片):


之所以這麼神奇,是因爲它在二叉查找樹的基礎上增加了着色和相關的性質使得紅黑樹相對平衡。
首先我們來看看紅黑樹的一些性質:
1、每個結點要麼是紅的,要麼是黑的。
2、
根結點是黑的。
3、
每個葉結點(葉結點即指樹尾端NIL指針或NULL結點)是黑的。
4、如果一個結點是紅的,那麼它的倆個兒子都是黑的。
5、對於任一結點而言,其到葉結點樹尾端NIL指針的每一條路徑都包含相同數目的黑結點。
正是紅黑樹的這5條性質,使得一棵n個結點的紅黑樹的高度始終保持在h = logn。

接下來我們就來介紹一下紅黑樹究竟爲什麼能自我平衡——旋轉起來吧
爲什麼要旋轉?因爲當你對一顆紅黑樹進行插入和刪除時,可能會違背了上面說到的5條性質。
爲了保持平衡,我們需要着色和旋轉。
樹的旋轉,分爲左旋和右旋,如圖(借用一下別人的圖片)
1.左旋

當進行左旋後,pivot的右兒子Y會替換當前結點的位置,並且Y的左子樹會成爲pivot的右子樹,以及pivot這棵樹會成爲Y的左子樹。

2.右旋

當進行右旋時,類似的,pivot的左兒子Y會替換pivot的位置,並且Y的右子樹會成爲pivot的左子樹,而pivot亦成爲了Y的右子樹。
以上就是旋轉,你只要想一下二叉查找樹的性質便明白了,對於任何一個結點,它的左子樹的所有結點的值都比它小,它的右子樹的所有結點的值都比它大,且它的左子樹和右子樹都是一棵二叉查找樹。

紅黑樹的插入與修復
首先對於插入,我們往往都是插入紅色的結點。
首先是不需要修復的兩種情況:
1、如果插入的是根結點,因爲原樹是空樹,此情況只會違反性質2,所以直接把此結點塗爲黑色。
2、如果插入的結點的父結點是黑色,由於此不會違反性質2和性質4,紅黑樹沒有被破壞,所以此時也是什麼也不做。
其次是需要修復的三種情況:
插入修復情況1:如果當前結點的父結點是紅色且祖父結點的另一個子結點(叔叔結點)是紅色
插入修復情況2:當前節點的父節點是紅色,叔叔節點是黑色,當前節點是其父節點的右子
插入修復情況3:當前節點的父節點是紅色,叔叔節點是黑色,當前節點是其父節點的左子
接下來我們來細講以上三種情況的處理方法。

插入修復情況1:如果當前結點的父結點是紅色且祖父結點的另一個子結點(叔叔結點)是紅色
在此,我們只考慮父結點爲祖父左子的情況,當前結點是父左子的情況。
對策:將當前節點的父節點和叔叔節點塗黑,祖父結點塗紅,把當前結點指向祖父節點,從新的當前節點重新開始算法。
我們插入結點4
變化前:

變化後:


此時,當前結點是7(上面說到了把當前結點指向祖父結點)。
此時,你發現了什麼?變化後的圖形出現了插入修復情況2。

插入修復情況2:當前節點的父節點是紅色,叔叔節點是黑色,當前節點是其父節點的右子
對策:當前節點(7)的父節點(2)做爲新的當前節點,以新當前節點(2)爲支點左旋。
變化前:

變化後:

很簡單吧。
此時,當前結點是2。
你又發現了什麼?變化後的圖形出現了插入修復情況3。

插入修復情況3:當前節點的父節點是紅色,叔叔節點是黑色,當前節點是其父節點的左子
解法:父節點變爲黑色,祖父節點變爲紅色,在祖父節點爲支點右旋。
變化前:

變化後:

此時再來看看這棵樹,確實是一棵紅黑樹了,滿足了上面的5個條件。

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