紅黑樹

1.紅黑樹的意義node

  [1]二叉查找樹在極端的插入狀況下,操做時間複雜度會變爲O(n),可是平衡二叉樹能夠一直維持在O(lg(n))。所以平衡二叉查找樹的效率很高,紅黑樹是一種自平衡二叉查找樹的實現方式,這即是紅黑樹的意義。linux

2.紅黑樹性質spa

  [1]節點是紅色或黑色。
  [2]根節點是黑色。
  [3]每一個葉節點(NIL節點,空節點)是黑色的。
  [4]每一個紅色節點的兩個子節點都是黑色。(從每一個葉子到根的全部路徑上不能有兩個連續的紅色節點)
  [5]從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點。code

3.變色、左旋和右旋blog

  [1]變色, 目的是進行操做後能夠(更趨近於)保持紅黑樹的性質。遞歸

  [2]左旋和右旋是變動節點在樹中的位置,目的是進行這些操做後能夠(更趨近於)保持紅黑樹的性質。源碼

4.刪除操做class

  紅黑樹的刪除和二叉查找樹的刪除操做是同樣的,只是多了一個修復平衡的流程。  效率

  總體流程:首先按照二叉查找樹的方式刪除節點。以後判斷釋放節點的顏色,若是是紅色,則結束,不然進入修復流程,修復流程就是一個狀態機,直到走到完成狀態。二叉樹

  [1]按照二叉查找樹的刪除流程:

    1)若是刪除節點的右子樹爲空,則把左節點接到刪除節點位置。此時,刪除節點就是釋放節點。
    2)若是刪除節點的左子樹爲空,則把右節點接到刪除節點位置。此時,刪除節點就是釋放節點。
    3)若是左右都不爲空,則把刪除節點的左子樹的最右節點(釋放節點,也就是刪除節點的後繼節點)替換到要刪除的節點,而後把釋放節點的左子樹接到其父節點上面。此時,後繼節點就是釋放節點。
  [2]若是釋放節點的顏色是紅色,則操做結束。不然,釋放節點的顏色是黑色,而且釋放節點只可能最多有一個子節點,把釋放節點(刪除節點或者後繼節點)的子節點做爲當前節點,釋放節點的父節點做爲父節點,進入狀態機。

  [3]修復(狀態機),循環執行如下操做:

    1)若是當前節點是紅色,則把當前節點塗黑,操做結束。

    2)若是當前節點是黑色,且兄弟節點是紅色,則進行操做:兄弟節點塗黑,父節點塗紅,對父節點進行左旋。(此時,當前節點的父節點沒變,可是兄弟節點變爲黑色)。

    3)若是當前節點是黑色,且兄弟節點是黑色,且兄弟節點的兩個子節點都是黑色,則進行操做:兄弟節點塗紅,將父節點做爲當前節點(附帶的操做就是更新父節點爲以前節點的祖父節點)。

    4)若是當前節點是黑色,且兄弟節點是黑色,且兄弟節點的右子節點是黑左子節點是紅,則進行操做:兄弟節點塗紅,兄弟左子節點塗黑,對兄弟節點進行右旋。(此時,當前節點的父節點沒變,可是兄弟節點的右子節點變爲紅色)。

    5)若是當前節點是黑色,且兄弟節點是黑色,且兄弟節點的右子節點是紅左子節點任意,則進行操做:兄弟節點的顏色塗成父節點的顏色,父節點塗黑,兄弟節點的右子節點塗黑,對父節點進行左旋,將根節點塗黑,操做結束。

    以上是當前節點是父節點左子節點的狀況,若是是右子節點,只是作了對稱處理(例如,對某個狀態,做爲左子節點時作左旋,而做爲右子節點作右旋)。

5.插入操做

  紅黑樹的刪除和二叉查找樹的插入操做是同樣的,只是多了一個修復平衡的流程。

  總體流程:首先按照二叉查找樹的方式插入節點,把插入節點塗紅。以後進入修復流程,修復流程就是一個狀態機,直到走到完成狀態。最後把根節點塗黑。

  [1]按照二叉查找樹的插入流程:小於根的往左子樹遞歸插入,不然往右子樹遞歸插入。插入的節點一定是插到最下面那一層,不會插入到樹的中間位置。

      初始把剛插入的節點塗紅(塗紅不會影響規則5,所以只須要處理更少的條件),把剛插入的節點做爲當前節點。

  [2]修復(狀態機),循環執行如下操做:

    1)若是當前節點的父節點是空,狀態機完成。

    2)若是當前節點的父節點是黑色,狀態機完成。

    3)若是當前節點的父節點是紅色,叔叔節點是紅色,則執行操做:將當前節點的父節點塗黑,叔叔節點塗黑,祖父節點塗紅,再將祖父節點做爲當前節點。

    4)若是當前節點的父節點是紅色,叔叔節點是黑色,且當前節點是其父節點的右子節點,則執行操做:對當前節點的父節點執行左旋,並把當前節點的父節點做爲當前節點(附帶更新當前節點的父節點(就是以前的節點))。

    5)若是當前節點的父節點是紅色,叔叔節點是黑色,且當前節點是其父節點的左子節點,則執行操做:對當前節點的父節點塗黑,祖父節點塗紅,對祖父節點執行右旋。

    最後把根節點塗黑,結束。

    以上是當前節點是父節點左子節點的狀況,若是是右子節點,只是作了對稱處理(例如,對某個狀態,做爲左子節點時作左旋,而做爲右子節點作右旋)。

 6.總結

  [1]紅黑樹的插入和刪除和二叉查找樹的方式是同樣的,以後多了一個修復流程,主要就是修復流程的狀態機,對於某一個狀態來講,須要進行一系列的操做,進行這個操做的目的是爲了進入下一個狀態,下一個狀態確定更趨近於樹的平衡。

  [2]關於變色、左旋和右旋,這些操做的目的是爲了讓樹的當前狀態更趨於平衡,這個也是處理紅黑樹的關鍵,即何時須要變色、旋轉,爲什麼變色、旋轉後能夠更趨近於平衡,這個也須要在實踐中熟練。

  [3]對於插入修復狀態機的第4個狀態說明:"對當前節點的父節點執行左旋",這個操做結束後,當前節點和父節點的位置會互換,所以把父節點做爲當前節點後,當前節點的父節點就是以前的節點,代碼就是:

register struct rb_node *tmp;
__rb_rotate_left(parent, root);        //對父節點左旋
tmp = parent;                          //
parent = node;                         //父節點做爲當前節點,同時更新當前節點的父節點
node = tmp;                            //

  [4]代碼,參照linux內核紅黑樹源碼。

相關文章
相關標籤/搜索