數據結構 —— 紅黑樹

紅黑樹

紅黑樹本質上是二叉平衡查找樹,二叉平衡查找樹有很多種,包括AVL樹,Splay Tree(伸展樹)、Treap(樹堆)等

紅黑樹是平衡二叉查找樹中的一種,也是最常用的一種。

 

二叉查找樹在頻繁的動態更新過程中,可能會出現樹的高度遠大於 log2n 的情況,從而導致各個操作的效率下降。

極端情況下,二叉樹會退化爲鏈表,時間複雜度會退化到 O(n)。

要解決頻繁動態更新後複雜度退化的問題,我們就需要平衡二叉查找樹。

 

平衡二叉查找樹

平衡二叉樹的嚴格定義是這樣的:二叉樹中任意一個節點的左右子樹的高度相差不能大於 1

首先,滿二叉樹和完全二叉樹肯定都是平衡二叉樹,但是非完全二叉樹也可能是平衡二叉樹。

 

最先被髮明的平衡二叉查找樹是AVL樹。

它嚴格符合我剛講到的平衡二叉查找樹的定義,即任何節點的左右子樹高度相差不超過 1,是一種高度平衡的二叉查找樹。 

 

但實際上很多平衡二叉查找樹其實並沒有嚴格符合上面嚴格的定義。

就比如說紅黑樹,它從根節點到各個葉子節點的最長路徑,有可能會比最短路徑大一倍。

 

“平衡”

平衡二叉查找樹中“平衡”的意思,其實就是讓整棵樹左右看起來比較“對稱”、比較“平衡”。

不要出現左子樹很高、右子樹很矮的情況。

這樣就能讓整棵樹的高度相對來說低一些,相應的插入、刪除、查找等操作的效率高一些。

 

所以說一個平衡二叉樹,只要樹的高度不比 log2n 大很多(比如樹的高度仍然是對數量級的)。

儘管它不符合嚴格的平衡二叉查找樹的定義,但仍然可以說,這是一個合格的平衡二叉查找樹。

 

紅黑樹的要求

紅黑樹的英文是“Red-Black Tree”,簡稱 R-B Tree。它是一種不嚴格的平衡二叉查找樹。

之所以叫紅黑樹,是因爲紅黑樹中的節點,一類被標記爲黑色,一類被標記爲紅色。

除此之外,還有很多的要求:

一、 根節點是黑色的;

二、 每個葉子節點都是黑色的空節點(NIL),也就是說,葉子節點不存儲數據;

三、 任何相鄰的節點都不能同時爲紅色,也就是說,紅色節點是被黑色節點隔開的;

四、 每個節點,從該節點到達其可達葉子節點的所有路徑,都包含相同數目的黑色節點;

 

“近似平衡”

紅黑樹是一種近似平衡的二叉查找樹。

“平衡”的意思可以等價爲性能不退化。“近似平衡”就等價爲性能不會退化的太嚴重。

二叉查找樹很多操作的性能都跟樹的高度成正比。衡量平衡與否可以概念轉換一下。

一棵極其平衡的二叉樹(滿二叉樹或完全二叉樹)的高度大約是 log2n。

所以如果要證明紅黑樹是近似平衡的,我們只需要分析,紅黑樹的高度是否比較穩定地趨近 log2n 就好了。

 

實現紅黑樹的基本思想

魔方的復原解法是有固定算法的:遇到哪幾面是什麼樣子,對應就怎麼轉幾下。

你只要跟着這個復原步驟,就肯定能將魔方復原。

紅黑樹的平衡過程跟魔方復原非常神似,大致過程就是:遇到什麼樣的節點排布,我們就對應怎麼去調整。

只要按照固定的操作步驟,保持插入、刪除的過程,不破壞平衡樹的定義就行了。

 

左旋(rotate left)、右旋(rotate right)

左旋全稱其實是叫圍繞某個節點的左旋,右旋就叫圍繞某個節點的右旋。

左旋和右旋是紅黑樹進行平衡調整的基本操作。

左旋和右旋其實可以想象成一個定滑輪。

圍繞節點 X 的左旋:
拉住節點 X 左邊的 a 子樹,向下拉,將節點 Y 拉到節點 X 的位置,a 子樹仍是節點 X 的左子樹,而節點 X 成爲了節點 Y 的左子節點,那麼就將原先節點 Y 的左子樹 b 摘下來,變成節點 X 的右子樹;

同理,圍繞節點 X 的右旋:
拉住節點 X 右邊的 r 子樹,向下拉,將節點 Y 拉到節點 X 的位置,a 子樹仍是節點 Y 的左子樹,而節點 X 成爲了節點 Y 的右子節點,那麼就將原先節點 Y 的右子樹 b 摘下來,變成節點 X 的左子樹;

 

此時關注節點是X,在紅黑樹平衡調整的過程中,一定要找準關注節點,不要搞丟、搞錯關注節點。 

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