1、簡述
紅黑樹是一種特殊的二叉樹,而且是優秀的自平衡查找樹,下圖爲紅黑樹的示例:html
紅黑樹具備如下幾大特性:算法
一、根節點爲黑色。網絡
二、全部節點都是黑色或紅色。性能
三、全部葉子節點(Null)都是黑色。學習
四、紅色節點的子節點必定是黑色的。spa
五、任意一個節點到其葉子節點的全部路徑上的黑色節點數量相同(黑色完美平衡二叉樹)。設計
以上的五大特定也是維持紅黑樹結構的基本規則,可是明白了這些規則,不表明咱們就明白了紅黑樹的設計原理及規則維持算法。指針
在咱們平常的工做中多多少少都會接觸到紅黑樹,特別是JDK1.8以後hashmap的底層採用了紅黑樹機構,接下來的博文中咱們會一點點弄明白如下幾個問題,也是筆者在學習以前不明白的兩個問題:htm
一、紅黑樹爲何要維持自平衡、自平衡的好處是什麼?blog
二、什麼是左旋,右旋,變色?
三、什麼條件下須要進行左旋、右旋、變色?
2、紅黑樹的自平衡
根據上一節紅黑樹特性第5點能夠知道,紅黑樹是一顆黑色完美平衡二叉樹,紅黑樹從根節點到葉子結點的最長路徑不會超過最短路徑的2倍;
這就保證了紅黑樹優秀的查找性能,其查找的時間複雜度爲O(logn);
當插入或刪除階段操做過程當中,會破壞此平衡結構,當平衡遭到破壞,程序會進行一系列操做來從新維持平衡,這一過程就是自平衡;這一系列操做就是左旋、右旋、變色。
一、左旋:
對當前節點進行左旋:當前節點的右子節點變爲父節點,原右子節點的左子節點變爲當前節點的右子節點,如圖演示(對150節點進行左旋):
上圖對150節點左旋:
- 把150節點的右子節點170變爲其父節點(170變爲150的父節點)。
- 把150節點的原右子節點170的左子節點160變爲其右子節點(160變爲150的右子節點)。
注意:
-
- 圖中只是示意圖,在第一步以後,170節點並無三個指向其餘節點的指針,這裏只是爲了理解起來更清晰
- 圖中只是進行左旋,尚未涉及變色問題,因此會看到父節點與子節點同色問題。
- 左旋操做涉及到的節點只是當前節點的右子節點和右子節點的左子節點兩個節點,其餘節點不變。
二、右旋:
對當前節點進行右旋:當前節點的左子節點變爲父節點,原左子節點的右子節點變爲當前節點的左子節點,如圖演示(對150節點進行右旋):
上圖對150節點進行右旋:
- 把150節點的左子節點130變爲其父節點(130變爲150的父節點)。
- 把150節點的原左子節點130的右子節點null節點變爲其左子節點(130的原右子節點null變爲150的左子節點)。
注意:
-
- 圖中只是示意圖,在第一步以後,130節點並無三個指向其餘節點的指針,這裏只是爲了理解起來更清晰
- 圖中只是進行左旋,尚未涉及變色問題,因此會看到父節點與子節點同色問題。
- 右旋操做涉及到的節點只是當前節點的左子節點和左子節點的右子節點兩個節點,其餘節點不變。
三、變色:
節點的變色:就是節點由紅色變成黑色或有黑色變成紅色。
而在實際的維持自平衡的過程當中變色過程有多是一個連鎖反應,而破壞平衡結果的操做有插入和刪除。
3、節點的插入
紅黑樹新節點的插入有可能會破壞現有的平衡結構,因此就須要進行節點的變色、左旋或者右旋操做來保持紅黑樹的平衡;但插入操做的狀況區分比較多,這也正是紅黑樹自平衡結構不容易理解的地方之一;
下圖就是插入的全部狀況,接下來會有針對每種狀況進行詳細講解:
其餘3種狀況很是簡單,這裏詳細說明第四種狀況:
C - current 當前節點,P - parent 父節點,PP - 祖父節點,U - uncle 叔叔節點, O - 其餘節點
狀況四、P 爲紅色
4.一、P 爲紅色且 U 爲紅色 (如圖 4.1)
(1)將 P 設爲黑色
(2)將 U 設爲黑色
(3)將 PP 設爲紅色
(4)將 PP 設爲當前節點(這時 PP 就爲 C 節點了),重複狀況4判斷
4.二、P 爲紅色且 U 不存在或爲黑色
4.2.一、P 是左節點,C 左節點 (P 爲紅色且 U 不存在或爲黑色)(如圖4.2.1)
(1)將 P 設爲黑色
(2)將 PP 設爲紅色
(3)對 PP 進行右旋
4.2.二、P 是左節點,C 右節點 (P 爲紅色且 U 不存在或爲黑色)(如圖4.2.2)
(1)對 P 進行左旋
(2)設 PP 爲當前節點
(3)此時結構變爲 4.2.1 結構,繼續進行 4.2.1 操做
4.2.三、P 是右節點,C 右節點 (P 爲紅色且 U 不存在或爲黑色)(如圖4.2.3)
(1)將 P 設爲黑色
(2)將 PP 設爲紅色
(3)對 PP 進行左旋
4.2.四、P 是右節點,C 左節點 (P 爲紅色且 U 不存在或爲黑色)(如圖4.2.4)
(1)對 P 進行右旋
(2)設 PP 爲當前節點
(3)此時結構變爲 4.2.3 結構,繼續進行 4.2.3 操做
節點插入總結:
-
- 當前節點(新插入的節點)會在旋轉變色以前就設置爲紅色;爲何插入節點爲紅色?由於根據紅黑樹的特性,當父節點爲黑色時,不須要作自平衡操做,若是爲黑色,那麼插入後褐色層次增長了,破壞特性5。
- 在4.1狀況中(P爲紅色且U爲紅色)若是重複遞歸判斷到根節點,把根節點設置成了紅色,則根據特性1,必須把根節點變回黑色,此時紅黑樹的黑色節點層次就增長了一層(自底向上生長)。
4、節點的刪除
紅黑樹的節點插入比較複雜,刪除操做更加複雜,但掌握了規律理解起來就簡單多了;
說到節點刪除以前,須要先了解一下前繼節點和後繼節點的概念,筆者學習過程當中看到一個很是容易理解的描述,以下圖:
把全部的節點投射到X軸上,這時全部的節點都是自左至右排好的,這樣某個節點的左邊的節點就是它的前繼節點,右邊的節點就是它的後繼節點。
由上圖能夠看到,後繼節點是右子樹的最左節點,前繼節點是左子樹的最右節點。
如150節點的前繼節點就是130,後繼節點就是160。
節點刪除後空出的位置須要找到其後繼節點或前繼節點進行補位,若是被刪除的節點沒有子節點還好,要是有子節點,不補位的話樹就散了;而且補位以後有可能會破壞紅黑樹的平衡結構,這時就須要進行自平衡了。
因此節點的刪除過程能夠理解爲尋找後繼節點或前繼節點(通常習慣用後繼幾點)進行補位後進行自平衡的過程;這樣理解,節點刪除問題就能夠轉換爲補位節點(後繼節點)的問題,補位完成後節點的顏色變爲被刪除的顏色。
而這一結果再簡單就能夠理解爲:補位節點(後繼節點)的刪除的自平衡問題,後繼節點老是在樹的最底層。
這樣一來就能夠區分補位節點的幾種狀況:
R - replace 補位節點,P - parent 父節點,PP - 祖父節點,B - brother 兄弟節點,BL - brother left 兄弟節點左子節點,BR - brother right 兄弟節點右子節點, O - 其餘節點
狀況1: R 爲紅色
狀況1比較簡單,紅色節點不影響紅黑樹的自平衡結構,因此直接補位,並把顏色轉換爲被刪除節點的顏色。
狀況2: R 爲黑色
2.一、R 爲左子節點
2.1.一、R 爲黑色且爲左子節點,B 爲紅色(如圖 2.1.1)
(1)、將 B 設爲黑色
(2)、將 P 設爲紅色
(3)、對 P 進行左旋,獲得 2.1.2.3 狀況
(4)、按照 2.1.2.3 狀況進行處理
2.1.二、R 爲黑色且爲左子節點,B 爲黑色
2.1.2.一、R 爲黑色且爲左子節點,B 爲黑色,BR 爲紅色,BL 爲任意(如圖 2.1.2.1)
(1)、將 B 設爲 P 的顏色
(2)、將 P 設爲黑色
(3)、將 BR 設爲黑色
(4)、對 P 進行左旋
在此處有幾個問題,注意上圖框出的部分
一、爲何此處不符合自平衡結構?
回答:節點的刪除是先找到補位節點(後繼節點),而後自平衡處理,而後才進行補位,因此此處的 R 以後會移走的,因此仍是符合自平衡結構。
二、BL 可能爲黑色節點麼?
回答:BL 不可能爲黑色節點,但其可能爲黑色葉子節點(NULL節點),下邊用窮舉法進行證實;
咱們知道,在節點刪除以前(第一次刪除),紅黑樹是保持平衡結構的,那麼若是 BL 爲黑色,那麼有一下幾種狀況:
1)P 爲黑色,BL 爲黑色,以下圖(1),不平衡,不成立。
2)P 爲紅色,BL 爲黑色,以下圖(2),不平衡,不成立。
3)P 爲紅色,BL 爲黑色葉子節點(NULL),以下圖(3),平衡,成立。
4)P 爲黑色,BL 爲黑色葉子節點(NULL),以下圖(4),平衡,成立。
5)BL 爲紅色,以下圖(5),平衡,成立。
綜上:BL 只可能爲紅色節點或黑色葉子節點(NULL)。
2.1.2.二、R 爲黑色且爲左子節點,B 爲黑色,BR 爲黑色,BL 爲紅色(如圖 2.1.2.2)
(1)、將 B 設爲紅色
(2)、將 BL 設爲黑色
(3)、對 B 進行右旋,獲得 2.1.2.1 狀況
(4)、按照 2.1.2.1 狀況進行處理
2.1.2.三、R 爲黑色且爲左子節點,B 爲黑色,BR 爲黑色(NULL),BL 爲黑色(NULL)(如圖 2.1.2.3)
(1)、將 B 設爲紅色
(2)、將 P 做爲新的補位節點
(3)、從新進行刪除節點處理
須要注意:
-
- 這時 P 就是 將要被移走的 R 的補位節點(後繼節點)。
- 此種狀況下其實 BL,BR 都是黑色的葉子節點(NULL)。
- B 變爲紅色是的緣由是整顆子樹都是黑色的節點,R 移走後,不管如何操做都沒辦法在子樹內自平衡,因此,最簡單的操做把 B 變爲紅色,這樣就自平衡了;可是這樣一來 子樹內部的黑色節點層數少了一層,這樣從 P 子樹的上一層數來看就是不平衡的了,因此要將 P 當作新的補位節點,進行自平衡操做,自底向上,直至根節點。
2.二、R爲右子節點
2.2.一、R 爲黑色且爲右子節點,B 爲紅色(如圖 2.2.1)
(1)、將 B 設爲黑色
(2)、將 P 設爲紅色
(3)、對 P 進行右旋,獲得 2.2.2.3 狀況
(4)、按照 2.2.2.3 狀況進行處理
2.2.二、R 爲黑色且爲右子節點,B 爲黑色
2.2.2.一、R 爲黑色且爲右子節點,B 爲黑色,BL 爲紅色,BR 爲任意(如圖 2.2.2.1)
(1)、將 B 設爲 P 的顏色
(2)、將 P 設爲黑色
(3)、將 BL 設爲黑色
(4)、對 P 進行右旋
注意:
此種狀況請參考 2.1.2.1中的問題與回答。
2.2.2.二、R 爲黑色且爲右子節點,B 爲黑色,BL 爲黑色,BR 爲紅色(如圖 2.2.2.2)
(1)、將 B 設爲紅色
(2)、將 BR 設爲黑色
(3)、對 B 進行左旋,獲得 2.2.2.1 狀況
(4)、按照 2.2.2.1 狀況進行處理
2.2.2.三、R 爲黑色且爲右子節點,B 爲黑色,BL 爲黑色(NULL),BR 爲黑色(NULL)(如圖 2.2.2.3)
(1)、將 B 設爲紅色
(2)、將 P 做爲新的補位節點
(3)、從新進行刪除節點處理
須要注意:
參考 2.1.2.3 下方的須要注意說明
節點刪除總結:
- 節點的刪除狀況比較多,但左右子節點狀況是對稱的,理解了其中一種,另外一種也很快會理解。
- 補位節點能夠用前繼節點代替,也能夠用後繼節點代替,通常習慣用後繼節點。
- 節點刪除過程是先找到補位節點,而後進行自平衡處理,而後纔會移除補位節點,即帶補位節點的自平衡。
- 在全黑節點的狀況下,可能發相似遞歸的生自底向上的尋找補位節點的過程,到根節點爲止。
- 自平衡的順序能夠理解爲,先本身處理,處理不了找兄弟節點參與,還處理不了找父節點參與,還處理不了讓父節點找父節點的兄弟處理,以此類推。
5、紅黑樹總結
經過上邊對紅黑樹的詳細諒解,咱們就能夠回答開始提出的問題了。
一、紅黑樹爲何要維持自平衡、自平衡的好處是什麼?
答:紅黑樹是一個高效的查詢樹,保持平衡結構,能夠保證從根節點到葉子節點的最長路徑不超過最短路徑的兩倍,能夠保證查詢效率。
二、什麼是左旋,右旋,變色?
答:左旋、右旋、變色都是對節點所在子樹的操做,以節點爲基進行變化保持樹的平衡的操做。
三、什麼條件下須要進行左旋、右旋、變色?
答:當發生節點插入或刪除操做時,紅黑樹的平衡被破壞,這是就要根據具體的狀況進行自平衡操做,即左旋、右旋或變色。
- 紅黑樹的結構比較複雜,不管是節點的插入仍是刪除,都有可能破壞自平衡結構,而自平衡過程最複雜狀況多是自底向上處理,直到根節點。
- 紅黑樹是平衡二叉樹,但不是完美的平衡二叉樹,只是黑色完美的平衡二叉樹(性質5)
- 紅黑樹的五條性質任意一套被破壞都觸發自平衡操做。
- 紅色節點的子節點必定是黑色,但黑色節點的子節點則能夠是紅色和黑色任意一種,便可以有相鄰的兩層節點都是黑色的狀況,如圖:
此博客爲筆者參考網絡上各種文章總結性書寫,原創手打,若有錯誤歡迎指正。
原文出處:https://www.cnblogs.com/MouseDong/p/11276211.html