(轉)五分鐘搞懂什麼是紅黑樹(全程圖解)

轉:http://www.360doc.com/content/18/0904/19/25944647_783893127.shtml

前戲

紅黑樹,對很多童鞋來說,是既熟悉又陌生。熟悉是因爲在校學習期間,準備面試時,這是重點。然後經過多年的荒廢,如今已經忘記的差不多了。如果正在看文章的你,馬上快要畢業,面臨着找工作的壓力;又或者你覺得需要將這塊知識重新複習一遍;又或者只是看看,那麼恭喜你,賺到了。那麼我將帶領大家重新認識下紅黑樹,用簡單的語言,搞懂紅黑樹。

在學習紅黑樹之前,咱們需要先來理解下二叉查找樹(BST)。

二叉查找樹

要想了解二叉查找樹,我們首先看下二叉查找樹有哪些特性呢?

1, 左子樹上所有的節點的值均小於或等於他的根節點的值

2, 右子數上所有的節點的值均大於或等於他的根節點的值

3, 左右子樹也一定分別爲二叉排序樹

我們來看下圖的這棵樹,他就是典型的二叉查找樹

五分鐘搞懂什麼是紅黑樹(全程圖解)

那問題來了,爲什麼一定要這種結構呢?換句話說這樣的結構有什麼好處呢?我們就來查找下值爲10的節點。它怎麼一步步的找到這個節點的?步驟是怎樣的?接着往下看。

1, 查找到根節點9,看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

2, 由於10大於9的,所以查找到右孩子13,看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

3, 又因爲10是小與13的,所以查找到左孩子11,看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

4, 這一步相比不用說了大家也都知道了,找到了左孩子,然後發現正好是10 。恰好是正要尋找的值。

五分鐘搞懂什麼是紅黑樹(全程圖解)

可能又有童鞋會問,這不是二分查找的思想嗎?確實,查找所需的最大次數等同於二叉查找樹的高度。當然在插入節點的時候,也是這種思想,一層一層的找到合適的位置插入。但是二叉查找樹有個比較大的缺陷,而且這個缺陷會影響到他的性能。我們先來看下有一種情況的插入操作:

如果初始的二叉查找樹只有三個節點,如下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

我們依次插入5個節點:7,6,5,4,3,。看下圖插入之後的圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

看出來了嗎?有沒有覺得很彆扭,如果根節點足夠大,那是不是“左腿”會變的特別長,也就是說查找的性能大打折扣,幾乎就是線性查找了。

那有沒有好的辦法解決這個問題呢?解決這種多次插入新節點而導致的不平衡?這個時候紅黑樹就登場了。

紅黑樹

紅黑樹就是一種平衡的二叉查找樹,說他平衡的意思是他不會變成“瘸子”,左腿特別長或者右腿特別長。除了符合二叉查找樹的特性之外,還具體下列的特性:

1. 節點是紅色或者黑色

2. 根節點是黑色

3. 每個葉子的節點都是黑色的空節點(NULL)

4. 每個紅色節點的兩個子節點都是黑色的。

5. 從任意節點到其每個葉子的所有路徑都包含相同的黑色節點。

看下圖就是一個典型的紅黑樹:五分鐘搞懂什麼是紅黑樹(全程圖解)

很多童鞋又會驚訝了,天啊這個條條框框也太多了吧。沒錯,正式因爲這些規則,才能保證紅黑樹的自平衡。最長路徑不超過最短路徑的2倍。

當插入和刪除節點,就會對平衡造成破壞,這時候需要對樹進行調整,從而重新達到平衡。那什麼情況下會破壞紅黑樹的規則呢?

1,我們看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

向原來的紅黑樹插入值爲14的新節點,由於父節點15是黑色節點,所以這種情況沒有破壞結構,不需要做任何的改變。

2,向原樹插入21呢?,看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

由於父節點22是紅色節點,因此這種情況打破了紅黑樹的規則4,必須作出調整。那麼究竟該怎麼調整呢?有兩種方式【變色】和【旋轉】分爲【左旋轉】和【右旋轉】。

【變色】:

爲了符合紅黑樹的規則,會把節點紅變黑或者黑變紅。下圖展示的是紅黑樹的部分,需要注意節點25並非根節點。因爲21和22鏈接出現紅色,不符合規則4,所以把22紅變黑:

五分鐘搞懂什麼是紅黑樹(全程圖解)

但這樣還是不符合規則5,所以需要把25黑變紅,看下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

你以爲現在結束了?天真,因爲25和27又是兩個連續的紅色節點(規則4),所以需要將27紅變黑。

五分鐘搞懂什麼是紅黑樹(全程圖解)

終於結束了,都滿足規則了,舒服多了。

【左旋轉】

也就是逆時針旋轉兩個節點,使父節點被自己的右孩子取代,而自己成爲自己的左孩子,聽起來嚇死人,直接看圖吧:

五分鐘搞懂什麼是紅黑樹(全程圖解)

【右旋轉】

順時針旋轉兩個節點,使得自己的父節點被左孩子取代,而自己成爲自己的右孩子,看不懂直接看圖吧:

五分鐘搞懂什麼是紅黑樹(全程圖解)

看起來這麼複雜,到底怎麼用呢?確實很複雜,我們講下典型的例子,大家參考下:

以剛纔插入21節點的例子:

五分鐘搞懂什麼是紅黑樹(全程圖解)

首先我們需要做的是變色,把節點25以及下方的節點變色:

五分鐘搞懂什麼是紅黑樹(全程圖解)

由於17和25是連續的兩個紅色節點,那麼吧節點17變黑嗎?這樣是不行的,你想這樣一來不就打破了規則4了嗎,而且根據規則2,也不可能吧13變成紅色。變色已經無法解決問題了,所以只能進行旋轉了。13當成X,17當成Y,左旋轉試試看:

五分鐘搞懂什麼是紅黑樹(全程圖解)

五分鐘搞懂什麼是紅黑樹(全程圖解)五分鐘搞懂什麼是紅黑樹(全程圖解)

由於根節點必須是黑色,所以需要變色,結果如下圖:

五分鐘搞懂什麼是紅黑樹(全程圖解)

繼續,其中有兩條路徑(17-)8->6->NULL)的黑色節點個數不是3,是4不符合規則。

這個時候需要把13當做X,8當做Y,進行右旋轉:

五分鐘搞懂什麼是紅黑樹(全程圖解)五分鐘搞懂什麼是紅黑樹(全程圖解)五分鐘搞懂什麼是紅黑樹(全程圖解)

最後根據規則變色:

五分鐘搞懂什麼是紅黑樹(全程圖解)

這樣一來,我們終於結束了,經過調整之後符合規則。

那我們費這麼大力氣,這麼複雜,這東西用在哪裏,有哪些應用呢?

其實STL中的map就是用的紅黑樹。

總結:

紅黑色的大體思想就是上面描述的那樣,裏面還有很多情況要考慮,本文只是簡單的講述思想,大家有興趣可以去百度上看各種情況的考慮

 

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