每個結點為紅色或者黑色
根結點為黑色
每個葉結點為黑色*
如果乙個結點為紅色,則它的兩個子結點為黑色
對每個結點,從該結點到其後代葉子節點的簡單路徑上,均包含相同數目的黑色結點
*這裡的葉結點不是指使用者在樹最底層插入的新結點點,而是插入新結點後,新結點的兩個為 nil 的左右孩子
紅黑樹的這 5 個性質,保證紅黑樹盡量趨近於平衡:
紅黑樹在搜尋,尋找前繼結點,尋找後繼,插入和刪除結點,這些操作與二叉搜尋樹基本是相同的,區別在於插入和刪除後,會破壞紅黑樹的性質,因此需要對紅黑樹進行調整來恢復紅黑樹的性質。本文主要**的就是在插入和刪除結點後如何對紅黑樹進行調整
按照紅黑樹的性質,紅黑樹的結點有兩種顏色,紅色和黑色,另外紅黑樹刪除過程中,結點還有一種中間態,叫雙黑結點,我們分別表示為:
這種表示方式是根據紅黑樹的性質 5 進行設定的,便於我們計算從乙個結點到它的後代葉子節點路徑上的黑色結點數。如下圖
a 為乙個紅色結點,color = 0
b 為乙個黑色結點,color = 1
c 為乙個雙黑結點,color = 2
a 的父節點到 nil1 和 nil2 經過的黑點樹即為 0 + 1 + 2 = 3
上圖中,a 結點為 b 和 c 的父結點,可以理解為 a 為第一層,而 b 和 c 為第二層,當第二層結點的 color 加 1 時,第一層結點只需要減 1,即可維護樹的性質 5。同理當第二層結點的 color 減 1 時,第一層結點只需要加 1,也可維護樹的性質 5。舉幾個實際的例子:
紅黑樹的旋轉分為左旋和右旋,上圖中從左變換為右為對 c 結點進行左旋,從右變換為左為對 b 結點的右旋。如何變換可參考具體的演算法資料,這裡主要**的是旋轉對樹性質的影響以及如何恢復。
以左旋為例,b 和 c 旋轉分四種情況:
綜上所述,當乙個結點為黑色,其父節點也為黑色的情況下,是不能進行旋轉的,而當乙個結點為紅色,其父結點為黑色時,旋轉後需要交換兩個結點的顏色,其它兩種情況保持不變
為保證紅黑樹的性質 5,插入新結點時,新結點的顏色為紅色。
插入後我們會遇到以下幾種情況:
上面在 case 3 處,實際已經滿足紅黑樹的性質,但是我們原則是儘量減少紅黑樹中紅色結點的數量,因此做了一步顏色合併
紅黑樹結點的刪除與二叉樹刪除類似,唯一區別就是刪除後,如果紅黑樹性質被破壞需要進行修復
二叉樹刪除分四種情況(如上圖):
完成上面的變化後,我們來考慮紅黑樹刪除會有什麼影響:
按照上面的方法刪除後,紅黑樹的性質,實際上只有性質 1 發生了變化,因為出現了雙黑結點,這時我們需要對雙黑結點進行處理,對雙黑結點的處理分為四種情況:
1. 雙黑結點的兄弟結點為紅色
這種情況下,a 結點必為黑色(性質4),c 的兩個結點必定是不為 t.nil 的黑色結點,否則 a 到 b 的葉子結點會比 a 到 c 的葉子結點的黑結點數多 1,違反性質 5。如上圖,變化方式:
對 c 結點進行旋轉,c 變為黑色,a 變為紅色,這樣可以保證紅黑樹的性質不變(旋轉部分說明過)
變化後雙黑結點 b 的兄弟結點變為黑色結點 d,轉為下面 2,3,4 中的一種情況
2. 雙黑結點的兄弟結點為黑色,且其遠端侄結點為紅色
這種情況會出現上圖中的兩種情況,雙黑結點的父結點 a 為紅色或黑色,這種變化的通用步驟為:
1. 結點顏色合併,b 和其兄弟結點的顏色減 1,b 變為黑色,c 變為紅色,a 的顏色加 1,變為黑色或雙黑色
2. 變化後,c 和它的乙個子結點都為紅色(這種情況,在紅黑樹插入中遇到過,c 和 d 都在其父結點的同一邊),因此需要對 c 進行旋轉
3. 與插入時旋轉相同,旋轉後,c 和 a 交換顏色,此時 a 和 d 均為紅色,c 為黑色或者雙紅色
4. 進行顏色合併,a 和 d 顏色加 1 後均變為黑色,c 顏色減 1 變為紅色或黑色。原始 a 為紅色時,a 的父結點必然為黑色,因此 c 變為紅色後,其父結點為原始 a 的父結點,因此不需要繼續變化
綜上,這種變化,實際上是對 c 進行旋轉(雙黑結點的兄弟結點,如果其在 a 的右子樹則左旋,在左子樹則右旋),然後將 a,b,d 都變為黑色,c 的顏色變為 a 的原始顏色
3. 雙黑結點的兄弟結點為黑色,且其近端侄結點為紅色
與情況 2 類似,這種情況會出現上圖中的兩種情況,雙黑結點的父結點 a 為紅色或黑色,這種變化的通用步驟為:
1. 結點顏色合併,b 和其兄弟結點的顏色減 1,b 變為黑色,c 變為紅色,a 的顏色加 1,變為黑色或雙黑色
2. 變化後,c 和它的乙個子結點都為紅色(這種情況,在紅黑樹插入中遇到過,c 和 d 不在其父結點的同一邊),因此需要對 d 進行兩次旋轉
3. 與插入時旋轉相同,旋轉後,d 和 a 交換顏色,此時 a 和 c 均為紅色,d 為黑色或者雙紅色
4. 進行顏色合併,a 和 c 顏色加 1 後均變為黑色,d 顏色減 1 變為紅色或黑色。原始 a 為紅色時,a 的父結點必然為黑色,因此 d 變為紅色後,其父結點為原始 a 的父結點,因此不需要繼續變化
綜上,這種變化,實際上是對 d 進行兩次旋轉(雙黑結點的兄弟結點的紅色子結點,如果其在 c 的右子樹則先左旋再右旋,在左子樹則先右旋再左旋),然後將 a,b,c 都變為黑色,d 的顏色變為 a 的原始顏色
4. 雙黑結點的兄弟結點為黑色,且其侄結點均為黑色
這種情況,直接對 b 的父結點 a 進行顏色合併,b 和它的兄弟結點 c 顏色減 1,b 變為黑色,c 變為紅色,a 的顏色加 1,變為黑色或雙黑色,這時因為 c 的子結點均為黑色,不需要對 c 進行調整。
a 如果變為黑色,則調整結束,如果變為雙黑色,則 a 變為新的雙黑結點,符合情況 1-4 中的其中一種,再進行變化。如果 a 變為雙黑色且為根節點,將其變為黑結點後結束
紅黑樹的插入和刪除
上一章講述了紅黑樹得相關性質,我們了解到紅黑樹確實是平衡二叉樹,在時間複雜度為o lg n 比二叉搜尋樹效能更好,效能變好的前提是演算法更加複雜了,下面講述紅黑樹的插入和刪除操作,希望對大家有所幫助。紅黑樹的插入操作和二叉搜尋樹大致相同,不同點是在將節點x插入紅黑樹後,此時的紅黑樹可能會違反紅黑樹的...
關於紅黑樹的插入和刪除
定義 紅黑樹是一棵二叉搜尋樹。它在每個結點每個結點上新增乙個儲存位來表示顏色,可以是紅色或者黑色。通過對任何一條從根到葉子結點的簡單路徑上各個結點的顏色進行約束。紅黑樹保證確保沒有一條路徑會比其他路徑長出兩倍,因而近似是平衡的。性質 1 每個結點或者是紅色或者是黑色 2 根結點是黑色的 3 每個葉子...
紅黑樹之二(刪除節點)
紅黑樹的另乙個重要的操作是刪除節點,它也可以分為兩步 找到要刪除的節點,並刪除它 對樹進行調整使得樹滿足紅黑樹的要求 從排序樹中刪除節點的思路是一樣的,首先找到要刪除的節點,並做如下處理 如果該節點不存在非空子節點,則直接刪除它 如果該節點存在乙個非空子節點,則用其非空子節點替換其位置即可 如果該節...