數據結構與算法——紅黑樹

紅黑樹

  1、定義:

  紅黑樹是一個自平衡二叉查找樹,平衡二叉樹是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。做爲二叉查找樹,紅黑樹普遍的被應用於各類數據結構中,例如HashMap(jdk8以後),TreeMap。算法

  2、性質:

  爲了實現紅黑樹的自平衡及二叉查找樹的特色,紅黑樹具備以下性質:數據結構

性質1. 節點是紅色或黑色。
性質2. 根節點是黑色。
性質3. 每一個葉節點(NIL節點,空節點)是黑色的。
性質4. 每一個紅色節點的兩個子節點都是黑色。
性質5. 從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點。
   注意:四、5 兩點保證了:從每一個葉子到根的全部路徑上不能有兩個連續的紅色節點,從而保證了最長分支不會超過最短分支長度的二倍

  3、紅黑樹的旋轉:

在紅黑樹構建過程當中,爲了維護紅黑樹的平衡性,會對樹的節點進行左旋或右旋。爲了更好的理解紅黑樹的構建,先用兩組圖片描述了典型的紅黑樹的左旋案例。理解了左旋也就理解了右旋的概念。
 

 

4、紅黑樹構建:

    如下面這顆紅黑樹舉例,演示節點增長和刪除的過程:spa

圖1設計

 

新增節點步驟

      一、將新增節點按照普通的二叉查找樹插入到原來的紅黑樹中,並塗成紅色。

      將圖1的紅黑樹新增「節點12」,按照二叉查找樹的特徵,將此節點插入到「節點11」的右側,造成以下圖2新的樹狀結構,剛好此結構也保持了紅黑樹的特徵,插入完成。blog

 

圖2圖片

      二、經過從新塗色以及旋轉將新的二叉查找樹的樹從新構建成紅黑樹。

      將紅色新節點插入到紅黑樹中,可能會違背紅黑樹的那些性質?class

性質1. 節點是紅色或黑色。(不會,由於插入的是紅色節點)
性質2. 根節點是黑色。(不會,按照二叉查找樹的方式插入節點不會改變根節點。例外狀況是空樹,此種狀況直接在算法最後將根節點塗成黑色便可)
性質3. 每一個葉節點(NIL節點,空節點)是黑色的。(不會,由於插入的是非空節點,而葉節點都是空節點)
性質4. 每一個紅色節點的兩個子節點都是黑色。(可能會)
性質5. 從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點。(不會,由於插入的是紅色節點,不會改變路徑上黑色節點的數目)
那麼,咱們只需經過必定的方法使這棵樹從新知足性質4便可,分析只有當新節點的父節點爲紅色節點時纔會出現這種狀況。
 

處理新節點(如下稱新節點爲z)父節點爲紅色節點可能會遭遇三種狀況,處理方案創建在z的父結點是左孩子基礎上,相反狀況判斷方法及旋轉方向均相反:

狀況1:z節點的叔父節點也爲紅色,此時祖父節點必定爲黑色(不然違背了性質4),此時須要將z的父節點和叔父節點都染成黑色,祖父節點染成紅色,z指向祖父節點。影響:不會對任何分支上的紅黑節點數產生影響,單純的是把z節點升高了兩層。
  • 考慮咱們將21節點插入圖2的紅黑樹中:造成圖3,z節點爲21
圖3
      • 將父節點和叔父節點塗成黑色,祖父節點塗成紅色,z指向祖父節點25:造成圖4,z節點爲25

圖4基礎

      • 依然符合狀況1,節點z的父節點與叔父節點均爲紅色,祖父節點黑色,將父節點及叔父節點均塗爲黑色,祖父節點塗爲紅色,因爲祖父節點爲根節點,再塗爲黑色造成新的紅黑樹,見圖5

圖5 jdk

狀況2:z節點的叔父節點爲黑色,且z節點爲右孩子,須要將z節點指向其父節點,再以新的z節點進行左旋。影響:將狀況2轉化爲狀況3二叉樹

      • 考慮圖5基礎上(此處案例設計問題,將圖5中的22改爲23,結構保持不變)插入節點22,造成圖6,z節點爲22

圖6

      • 自己爲紅色,父節點爲紅色,叔父節點爲黑色,且自身爲右孩子節點,那麼將z指向其父節點21節點,並以21節點進行左旋:造成圖7,z節點爲21。

圖7

狀況3:z的叔父節點是黑色的且z是一個左孩子,將z的父節點染黑,z的祖父節點染紅,而後以z的祖父節點進行右旋。影響:在兩次修改顏色後,會致使從根結點向左出發的全部路徑的黑高不變,而向右出發的全部路徑的黑高減1;而右旋操做會使黑高迴歸平衡。

      • 考慮圖7,z節點爲21,z的叔父節點22爲黑色且z是一個左孩子,將z的父節點22染黑,z的祖父節點23染紅:造成圖8,z節點爲21

 

圖8

      • 考慮圖8,z節點爲21,以z節點的祖父節點進行右旋,造成圖9,此時紅黑樹從新造成。

 

圖9

插入節點總結:

狀況1逐步提升z節點的層高,其致使的結果有兩個。

  一、z節點升高到根節點,將根節點染黑後,整顆樹迴歸紅黑樹特性;

  二、z節點的狀況轉化爲3(直接轉化爲3或轉化成2再轉化成3)

狀況3執行事後會迴歸紅黑樹的特性。

刪除節點步驟(刪除節點待補充示例圖)

一、將紅黑樹當成普通的二叉查找樹,進行節點刪除

        • 若是被刪除的節點沒有子節點,則直接刪除
        • 若是被刪除的節點只有一個子節點,則將此子節點頂替被刪除節點的位置
        • 若是被刪除的節點有兩個子節點,則找到左子樹的最大節點r(或者後繼節點也可),將此節點的數據放入被刪除的節點,同時刪除節點r(由於r是左子樹的最右節點,因此沒有右節點,刪除節點r能夠轉化成狀況1或狀況2)

二、經過旋轉和從新着色使二叉查找樹恢復紅黑樹的特性

分析:由於步驟1,可能會對紅黑樹的哪些特性產生影響?

性質1. 節點是紅色或黑色。(不會)
性質2. 根節點是黑色。(會,但能夠在算法着色最後,直接將紅色根節點染黑就能夠解決了)
性質3. 每一個葉節點(NIL節點,空節點)是黑色的。(不會)
性質4. 每一個紅色節點的兩個子節點都是黑色。(會)
性質5. 從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點。(會)
現爲被刪除節點命名爲N,通過步驟1的處理,N節點至多隻有一個非空子節點。根據節點N顏色的不一樣能夠分爲如下兩種狀況
  • N節點爲紅色節點:那麼N節點必定是有兩個葉子節點(由於N節點爲紅色,那麼其子節點必定爲黑色,若是子節點一個是葉子節點一個是非空子節點,那麼N節點左右子樹包含的黑色節點個數不相等,違背了紅黑樹的特性),那麼直接刪除節點N便可。
  • N節點爲黑色節點:能夠分爲兩種狀況,含有一個紅色子節點或含有兩個葉子節點(若是含有一個黑色的非空子節點,則左右分支黑色節點個數不等)

一、N節點包含了一個紅色非空子節點,則只須要把紅色子節點頂替N節點,並塗成黑色(這樣不會影響N節點如下各個分支黑色節點的個數),從新知足紅黑樹的特徵;

二、N節點包含了兩個葉子節點,刪除N節點後,代替N節點的爲其NIL子節點,依然命名爲N,該路徑上的黑色節點比其餘路徑上的黑色節點個數少了一個,N節點的父節點命名爲P,N的兄弟節點命名爲B,則還需分爲幾種case(注意:如下case均以N是父結點P的左孩子結點,若是是右孩子結點,那麼「左」和「右」應該對調):

case1:N爲根節點爲根節點,由於N爲NIL,則整顆樹爲空樹,知足了紅黑樹的特徵,結束。

case2:N的兄弟節點爲紅色,則將P和B節點的顏色對調後,以P節點爲支點進行左旋,而後進入case四、case5或case6

case3:N、P、B三個節點都爲黑色,則將B節點顏色塗爲紅色,此時P節點左右分支的黑節點數相等,但比不經過P節點的分支黑節點少一個,仍然須要按照這幾個case繼續處理P節點。

case4:P位紅色,N、B以及B的兩個子節點都爲黑色,則對調P和B的顏色,此時不影響經過B的黑色結點數量,可是在經過N的路徑上增長了一個黑色結點,可是N節點會被刪除後,知足了性質5.

case5:B的左節點爲紅色,右節點爲黑色,而且N爲P的左孩子,則B與其左孩子顏色對調後右旋,此時進入case6

case6:結點N的兄弟結點B是黑色的,B的右孩子是紅色的(右紅),而且結點N是父結點P的左孩子。此時將父結點P和兄弟結點S的顏色對調,再將S的右孩子變爲黑色,而後左旋父結點P。

相關文章
相關標籤/搜索