<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      一、簡述

      紅黑樹是一種特殊的二叉樹,并且是優(yōu)秀的自平衡查找樹,下圖為紅黑樹的示例:



      紅黑樹具有以下幾大特性:

      1、根節(jié)點為黑色。

      2、所有節(jié)點都是黑色或紅色。

      3、所有葉子節(jié)點(Null)都是黑色。

      4、紅色節(jié)點的子節(jié)點一定是黑色的。

      5、任意一個節(jié)點到其葉子節(jié)點的所有路徑上的黑色節(jié)點數(shù)量相同(黑色完美平衡二叉樹)。

      以上的五大特定也是維持紅黑樹結構的基本規(guī)則,但是明白了這些規(guī)則,不代表我們就明白了紅黑樹的設計原理及規(guī)則維持算法。


      在我們日常的工作中多多少少都會接觸到紅黑樹,特別是JDK1.8之后hashmap的底層采用了紅黑樹機構,接下來的博文中我們會一點點弄明白以下幾個問題,也是筆者在學習之前不明白的兩個問題:

      1、紅黑樹為什么要維持自平衡、自平衡的好處是什么?

      2、什么是左旋,右旋,變色?

      3、什么條件下需要進行左旋、右旋、變色?

      二、紅黑樹的自平衡

      根據(jù)上一節(jié)紅黑樹特性第5點可以知道,紅黑樹是一顆黑色完美平衡二叉樹,紅黑樹從根節(jié)點到葉子結點的最長路徑不會超過最短路徑的2倍;

      這就保證了紅黑樹優(yōu)秀的查找性能,其查找的時間復雜度為O(logn);

      當插入或刪除階段操作過程中,會破壞此平衡結構,當平衡遭到破壞,程序會進行一系列操作來重新維持平衡,這一過程就是自平衡;這一系列操作就是左旋、右旋、變色。?

      1、左旋:

      對當前節(jié)點進行左旋:當前節(jié)點的右子節(jié)點變?yōu)楦腹?jié)點,原右子節(jié)點的左子節(jié)點變?yōu)楫斍肮?jié)點的右子節(jié)點,如圖演示(對150節(jié)點進行左旋):



      上圖對150節(jié)點左旋:

      * 把150節(jié)點的右子節(jié)點170變?yōu)槠涓腹?jié)點(170變?yōu)?50的父節(jié)點)。
      * 把150節(jié)點的原右子節(jié)點170的左子節(jié)點160變?yōu)槠溆易庸?jié)點(160變?yōu)?50的右子節(jié)點)。
      注意:

      *
      * 圖中只是示意圖,在第一步之后,170節(jié)點并沒有三個指向其他節(jié)點的指針,這里只是為了理解起來更清晰
      * 圖中只是進行左旋,還沒有涉及變色問題,所以會看到父節(jié)點與子節(jié)點同色問題。
      * 左旋操作涉及到的節(jié)點只是當前節(jié)點的右子節(jié)點和右子節(jié)點的左子節(jié)點兩個節(jié)點,其他節(jié)點不變。
      2、右旋:

      對當前節(jié)點進行右旋:當前節(jié)點的左子節(jié)點變?yōu)楦腹?jié)點,原左子節(jié)點的右子節(jié)點變?yōu)楫斍肮?jié)點的左子節(jié)點,如圖演示(對150節(jié)點進行右旋):



      上圖對150節(jié)點進行右旋:

      * 把150節(jié)點的左子節(jié)點130變?yōu)槠涓腹?jié)點(130變?yōu)?50的父節(jié)點)。
      * 把150節(jié)點的原左子節(jié)點130的右子節(jié)點null節(jié)點變?yōu)槠渥笞庸?jié)點(130的原右子節(jié)點null變?yōu)?50的左子節(jié)點)。
      ?注意:

      *
      * 圖中只是示意圖,在第一步之后,130節(jié)點并沒有三個指向其他節(jié)點的指針,這里只是為了理解起來更清晰
      * 圖中只是進行左旋,還沒有涉及變色問題,所以會看到父節(jié)點與子節(jié)點同色問題。
      * 右旋操作涉及到的節(jié)點只是當前節(jié)點的左子節(jié)點和左子節(jié)點的右子節(jié)點兩個節(jié)點,其他節(jié)點不變。
      3、變色:

      節(jié)點的變色:就是節(jié)點由紅色變成黑色或有黑色變成紅色。

      而在實際的維持自平衡的過程中變色過程有可能是一個連鎖反應,而破壞平衡結果的操作有插入和刪除。?

      三、節(jié)點的插入


      紅黑樹新節(jié)點的插入有可能會破壞現(xiàn)有的平衡結構,所以就需要進行節(jié)點的變色、左旋或者右旋操作來保持紅黑樹的平衡;但插入操作的情況區(qū)分比較多,這也正是紅黑樹自平衡結構不容易理解的地方之一;

      下圖就是插入的所有情況,接下來會有針對每種情況進行詳細講解:



      其他3種情況非常簡單,這里詳細說明第四種情況:

      C -?current?當前節(jié)點,P -?parent?父節(jié)點,PP -?祖父節(jié)點,U -?uncle?叔叔節(jié)點, O -?其他節(jié)點?

      情況4、P?為紅色

      4.1、P?為紅色且?U?為紅色 (如圖 4.1)

      (1)將 P 設為黑色

      (2)將 U 設為黑色

      (3)將 PP 設為紅色

      (4)將 PP 設為當前節(jié)點(這時 PP?就為 C?節(jié)點了),重復情況4判斷

      ?

      ?

      4.2、P?為紅色且 U?不存在或為黑色?

      4.2.1、P?是左節(jié)點,C?左節(jié)點 (P?為紅色且 U?不存在或為黑色)(如圖4.2.1)


      (1)將 P 設為黑色

      (2)將 PP 設為紅色

      (3)對 PP?進行右旋

      ?

      4.2.2、P?是左節(jié)點,C?右節(jié)點 (P?為紅色且 U?不存在或為黑色)(如圖4.2.2)

      (1)對 P?進行左旋

      (2)設 PP?為當前節(jié)點

      (3)此時結構變?yōu)?4.2.1?結構,繼續(xù)進行 4.2.1 操作

      ?

      4.2.3、P?是右節(jié)點,C?右節(jié)點?(P?為紅色且 U?不存在或為黑色)(如圖4.2.3)

      (1)將 P 設為黑色

      (2)將 PP 設為紅色

      (3)對 PP?進行左旋



      4.2.4、P?是右節(jié)點,C?左節(jié)點?(P?為紅色且 U?不存在或為黑色)(如圖4.2.4)

      (1)對 P?進行右旋

      (2)設 PP?為當前節(jié)點

      (3)此時結構變?yōu)?4.2.3 結構,繼續(xù)進行 4.2.3 操作

      ?

      節(jié)點插入總結:

      *
      *
      當前節(jié)點(新插入的節(jié)點)會在旋轉變色之前就設置為紅色;為什么插入節(jié)點為紅色?因為根據(jù)紅黑樹的特性,當父節(jié)點為黑色時,不需要做自平衡操作,如果為黑色,那么插入后褐色層次增加了,破壞特性5。
      *
      在4.1情況中(P為紅色且U為紅色)如果重復遞歸判斷到根節(jié)點,把根節(jié)點設置成了紅色,則根據(jù)特性1,必須把根節(jié)點變回黑色,此時紅黑樹的黑色節(jié)點層次就增加了一層(自底向上生長)。
      ?四、節(jié)點的刪除

      紅黑樹的節(jié)點插入比較復雜,刪除操作更加復雜,但掌握了規(guī)律理解起來就簡單多了;

      說到節(jié)點刪除之前,需要先了解一下前繼節(jié)點和后繼節(jié)點的概念,筆者學習過程中看到一個非常容易理解的描述,如下圖:



      把所有的節(jié)點投射到X軸上,這時所有的節(jié)點都是自左至右排好的,這樣某個節(jié)點的左邊的節(jié)點就是它的前繼節(jié)點,右邊的節(jié)點就是它的后繼節(jié)點。

      由上圖可以看到,后繼節(jié)點是右子樹的最左節(jié)點,前繼節(jié)點是左子樹的最右節(jié)點。

      如150節(jié)點的前繼節(jié)點就是130,后繼節(jié)點就是160。


      節(jié)點刪除后空出的位置需要找到其后繼節(jié)點或前繼節(jié)點進行補位,如果被刪除的節(jié)點沒有子節(jié)點還好,要是有子節(jié)點,不補位的話樹就散了;并且補位之后有可能會破壞紅黑樹的平衡結構,這時就需要進行自平衡了。

      所以節(jié)點的刪除過程可以理解為尋找后繼節(jié)點或前繼節(jié)點(一般習慣用后繼幾點)進行補位后進行自平衡的過程;
      這樣理解,節(jié)點刪除問題就可以轉換為補位節(jié)點(后繼節(jié)點)的問題,補位完成后節(jié)點的顏色變?yōu)楸粍h除的顏色。

      而這一結果再簡單就可以理解為:補位節(jié)點(后繼節(jié)點)的刪除的自平衡問題,后繼節(jié)點總是在樹的最底層。

      這樣一來就可以區(qū)分補位節(jié)點的幾種情況:

      ?

      R -?replace?補位節(jié)點,P -?parent?父節(jié)點,PP -?祖父節(jié)點,B -?brother?兄弟節(jié)點,BL -?brother
      left?兄弟節(jié)點左子節(jié)點,BR -?brother right?兄弟節(jié)點右子節(jié)點, O -?其他節(jié)點?

      情況1:?R?為紅色

      情況1比較簡單,紅色節(jié)點不影響紅黑樹的自平衡結構,所以直接補位,并把顏色轉換為被刪除節(jié)點的顏色。

      情況2: R?為黑色

      2.1、R?為左子節(jié)點

      2.1.1、R?為黑色且為左子節(jié)點,B?為紅色(如圖 2.1.1)

      (1)、將 B 設為黑色
      (2)、將 P 設為紅色
      (3)、對 P 進行左旋,得到 2.1.2.3 情況
      (4)、按照 2.1.2.3 情況進行處理



      2.1.2、R?為黑色且為左子節(jié)點,B?為黑色

      2.1.2.1、R?為黑色且為左子節(jié)點,B?為黑色,BR?為紅色,BL?為任意(如圖 2.1.2.1)

      (1)、將 B 設為 P 的顏色
      (2)、將 P 設為黑色
      (3)、將 BR 設為黑色
      (4)、對 P 進行左旋



      在此處有幾個問題,注意上圖框出的部分

      1、為什么此處不符合自平衡結構?

      回答:節(jié)點的刪除是先找到補位節(jié)點(后繼節(jié)點),然后自平衡處理,然后才進行補位,所以此處的 R?之后會移走的,所以還是符合自平衡結構。

      2、BL?可能為黑色節(jié)點么?

      回答:BL?不可能為黑色節(jié)點,但其可能為黑色葉子節(jié)點(NULL節(jié)點),下邊用窮舉法進行證明;

      我們知道,在節(jié)點刪除之前(第一次刪除),紅黑樹是保持平衡結構的,那么如果 BL?為黑色,那么有一下幾種情況:

      1)P?為黑色,BL?為黑色,如下圖(1),不平衡,不成立。

      2)P?為紅色,BL?為黑色,如下圖(2),不平衡,不成立。

      3)P?為紅色,BL?為黑色葉子節(jié)點(NULL),如下圖(3),平衡,成立。

      4)P?為黑色,BL?為黑色葉子節(jié)點(NULL),如下圖(4),平衡,成立。

      5)BL?為紅色,如下圖(5),平衡,成立。

      綜上:BL?只可能為紅色節(jié)點或黑色葉子節(jié)點(NULL)。



      2.1.2.2、R?為黑色且為左子節(jié)點,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.3、R?為黑色且為左子節(jié)點,B?為黑色,BR?為黑色(NULL),BL?為黑色(NULL)(如圖 2.1.2.3)

      (1)、將 B 設為紅色
      (2)、將 P 作為新的補位節(jié)點
      (3)、重新進行刪除節(jié)點處理

      ?

      需要注意:

      *
      * 這時 P?就是?將要被移走的 R?的補位節(jié)點(后繼節(jié)點)。
      * 此種情況下其實 BL,BR?都是黑色的葉子節(jié)點(NULL)。
      * B?變?yōu)榧t色是的原因是整顆子樹都是黑色的節(jié)點,R?移走后,無論如何操作都沒辦法在子樹內自平衡,所以,最簡單的操作把
      B?變?yōu)榧t色,這樣就自平衡了;但是這樣一來?子樹內部的黑色節(jié)點層數(shù)少了一層,這樣從 P?子樹的上一層數(shù)來看就是不平衡的了,所以要將
      P?看成新的補位節(jié)點,進行自平衡操作,自底向上,直至根節(jié)點。
      2.2、R為右子節(jié)點

      2.2.1、R?為黑色且為右子節(jié)點,B?為紅色(如圖 2.2.1)

      (1)、將 B 設為黑色
      (2)、將 P 設為紅色
      (3)、對 P 進行右旋,得到 2.2.2.3 情況
      (4)、按照 2.2.2.3 情況進行處理



      2.2.2、R?為黑色且為右子節(jié)點,B 為黑色

      2.2.2.1、R?為黑色且為右子節(jié)點,B?為黑色,BL 為紅色,BR 為任意(如圖 2.2.2.1)

      (1)、將 B 設為 P 的顏色
      (2)、將 P 設為黑色
      (3)、將 BL 設為黑色
      (4)、對 P 進行右旋



      注意:

      此種情況請參考 2.1.2.1中的問題與回答。?

      2.2.2.2、R?為黑色且為右子節(jié)點,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.3、R?為黑色且為右子節(jié)點,B?為黑色,BL 為黑色(NULL),BR 為黑色(NULL)(如圖 2.2.2.3)

      (1)、將 B 設為紅色
      (2)、將 P 作為新的補位節(jié)點
      (3)、重新進行刪除節(jié)點處理

      ?

      需要注意:

      參考 2.1.2.3?下方的需要注意說明

      節(jié)點刪除總結:

      * 節(jié)點的刪除情況比較多,但左右子節(jié)點情況是對稱的,理解了其中一種,另一種也很快會理解。
      * 補位節(jié)點可以用前繼節(jié)點代替,也可以用后繼節(jié)點代替,一般習慣用后繼節(jié)點。
      * 節(jié)點刪除過程是先找到補位節(jié)點,然后進行自平衡處理,然后才會移除補位節(jié)點,即帶補位節(jié)點的自平衡。
      * 在全黑節(jié)點的情況下,可能發(fā)類似遞歸的生自底向上的尋找補位節(jié)點的過程,到根節(jié)點為止。
      * 自平衡的順序可以理解為,先自己處理,處理不了找兄弟節(jié)點參與,還處理不了找父節(jié)點參與,還處理不了讓父節(jié)點找父節(jié)點的兄弟處理,以此類推。
      五、紅黑樹總結?

      通過上邊對紅黑樹的詳細諒解,我們就可以回答開始提出的問題了。

      1、紅黑樹為什么要維持自平衡、自平衡的好處是什么?

      答:紅黑樹是一個高效的查詢樹,保持平衡結構,可以保證從根節(jié)點到葉子節(jié)點的最長路徑不超過最短路徑的兩倍,可以保證查詢效率。

      2、什么是左旋,右旋,變色?

      答:左旋、右旋、變色都是對節(jié)點所在子樹的操作,以節(jié)點為基進行變化保持樹的平衡的操作。

      3、什么條件下需要進行左旋、右旋、變色?

      答:當發(fā)生節(jié)點插入或刪除操作時,紅黑樹的平衡被破壞,這是就要根據(jù)具體的情況進行自平衡操作,即左旋、右旋或變色。

      * 紅黑樹的結構比較復雜,無論是節(jié)點的插入還是刪除,都有可能破壞自平衡結構,而自平衡過程最復雜情況可能是自底向上處理,直到根節(jié)點。
      * 紅黑樹是平衡二叉樹,但不是完美的平衡二叉樹,只是黑色完美的平衡二叉樹(性質5)
      * 紅黑樹的五條性質任意一套被破壞都觸發(fā)自平衡操作。
      * 紅色節(jié)點的子節(jié)點一定是黑色,但黑色節(jié)點的子節(jié)點則可以是紅色和黑色任意一種,即可以有相鄰的兩層節(jié)點都是黑色的情況,如圖:
      ?

      ?

      ?此博客為筆者參考網(wǎng)絡上各類文章總結性書寫,原創(chuàng)手打,如有錯誤歡迎指正。

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          日韩精品黄片 | 做爱网络视频在线看网站免费 | XXXXXL19D历史背景 | 靠逼视频免看 | 欧美日韩v | 欧美精品成人无码中文毛片不卡 | 女人扒开屁股让我添 | 国产一级a爱做片免费观看人与生 | 中文在线a 在线播放 | 草草影院欧美第一页 |