紅黑樹的用途、紅黑樹的插入刪除操作

紅黑樹首先是一棵二叉查找樹(BST),BST 滿足的性質如下:

  • 子樹上所有節點的值均小于或等于它的根節點的值;
  • 子樹上所有節點的值均大于或等于它的根節點的值;
  • 左右子樹? BST。

考慮向一棵 BST 中多次插入新節點的情況,如果插入的總是最大(小)值,會導致 BST 嚴重不平衡。為了解決這個問題,引入了自平衡的二叉查找樹——紅黑樹(BR-Tree)。紅黑樹的附加特性:

  1. 節點為黑色或紅色;
  2. 根節點為黑色;
  3. 每個葉子節點都是黑色的空節點(NIL);
  4. 每個紅色節點的兩個孩子節點都是黑色(保證從每個葉子到根的所有路徑上不能有兩個連續的紅色節點);
  5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點(保證了紅黑樹從根到葉子的最長路徑不會超過最短路徑的兩倍)。

紅黑樹的用途

1)廣泛應用在 C++ 的 STL 中,如 map 和 set 都是用紅黑樹實現的。
2)linux 進程調度,用紅黑樹管理進程控制塊
3)epoll 在內核中的實現,用紅黑樹管理事件塊
4)nginx 中,用紅黑樹管理 timer 等

紅黑樹的插入

插入的新節點 N 初始化為紅色
case 0.0
N 為根節點,直接變為黑色。over。
case 0.1
N 的父節點為黑色,無需調整。over。

case 0.0 與 case 0.1 示意圖

case 1
N 的父節點為紅色,無叔叔節點(父節點的兄弟節點)或叔叔節點為黑色,且 N 為右子。以父節點為新紅色節點 N,并以 N 為支點進行左旋。繼續判定旋轉后的節點 N 是否滿足性質。

case 1 示意圖 - 1

case 1 示意圖 - 2

case 2
N 的父節點為紅色,無叔叔節點(父節點的兄弟節點)或叔叔節點為黑色,且 N 為左子。將 N 的父節點變為黑色,祖父節點變為紅色,以祖父節點為支點進行右旋。

case 2 示意圖

case 1 與 case 2 示意圖

case 3
N 的父節點為紅色,叔叔節點(父節點的兄弟節點)也為紅色,將父節點與叔叔節點都變為黑色,祖父節點變為紅色。若祖父節點仍不滿足性質,則將祖父節點當做新紅色節點遞歸調整。最后強制根節點為黑色。

case 3 示意圖

紅黑樹的刪除

case 1
如果需要刪除的節點有兩個孩子,我們的做法是找到這個節點的中序后繼,將后繼節點中的數據拷貝至待刪除結點,然后刪除后繼節點。而后繼節點必然最多只有一個子節點,這樣我們就把刪除兩個孩子的節點轉為刪除一個孩子的節點(case 2)。
case 2
刪除只有一個孩子的節點,如果它兩個孩子都為空,即均為葉子,我們任意將其中一個看作它的孩子。(這里體現出來,在紅黑樹里特別指定葉子結點為 NIL 節點的作用,NIL 節點經常可以充當正常節點使用以使得算法的表達更加容易。)
 case 2.1
 若被刪除節點是紅色,它的父親和孩子一定是黑色的。所以我們可以簡單地用它的黑色孩子替換它。
 case 2.2
 若被刪除節點是黑色而它的孩子是紅色。用它的紅色孩子頂替上來并重繪為黑色。
 case 2.3
 若待刪除節點和它的子節點都是黑色,情況比較多,由簡單到復雜分為六小類。
 先來約定涉及到的節點的名稱。我們先用待刪除節點的孩子代替待刪除節點,并且記這個孩子為 N,記它的新的父節點為 P,它的兄弟節點為 S, S的左孩子為 SL,右孩子為 SR。
  case 2.3.1
  若 N 是新的根。無需改動,所有屬性都保持著。over。
  case 2.3.2
  P 為紅色,S 和 S 的兩個孩子都是黑色的。將 P 置為黑色,S 置為紅色。這樣,不經過 N 的路徑上的黑色結點數目并沒有發生變化,而經過 N 結點的路徑上黑色結點的數目增加了 1,剛好添補了這條路徑上刪除的黑色結點。所以紅黑樹又重新達到了平衡。

case 2.3.2 示意圖

  case 2.3.3
  S 是黑色,S 的右孩子是紅色,而 N 是它父親的左兒子。以 P 為支點左旋,這樣 S 成為 P 和 R 的父親。接著交換 N 的父親和 S 的顏色,并使 S 的右兒子為黑色。
case 2.3.3 示意圖(白色節點可以是紅色或黑色,但是在變換前后都必須指定相同的顏色)

  case 2.3.4
  S 是黑色,S 的左孩子是紅色,S 的右兒子是黑色,而 N 是它父親的左兒子。在這種情況下我們在 S 上做右旋,這樣 S 的左兒子成為 N 的新兄弟。我們接著交換 S 和它的新父親的顏色。所有路徑仍有同樣數目的黑色節點,但是現在N有了一個右兒子是紅色的黑色兄弟,所以我們進入了 case 2.3.3。N 和它的父親都不受這個變換的影響。
case 2.3.4 示意圖

  case 2.3.5
  S 是紅色。在這種情況下我們在 P 上做左旋,把紅色兄弟轉換成 N 的祖父。我們接著對調 N 的父親和祖父的顏色。盡管所有的路徑仍然有相同數目的黑色節點,現在 N 有了一個黑色的兄弟和一個紅色的父親,所以我們可以接下去按 case 2.3.2、case 2.3.3、case 2.3.3 來處理。
case 2.3.5 示意圖

  case 2.3.6
  P、S 和 S 的兒子都是黑色的。在這種情況下,我們簡單的重繪 S 為紅色。結果是通過 S 的所有路徑,都少了一個黑色節點。 因為刪除 N 的初始的父親使通過 N 的所有路徑少了一個黑色節點,這使事情都平衡了起來。 但是,通過 P 的所有路徑現在比不通過 P 的路徑少了一個黑色節點。要修正這個問題,我們要轉到 case 2.3.1,把 P 當做新的 N 重新平衡處理。
case 2.3.6

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • R-B Tree簡介 R-B Tree,全稱是Red-Black Tree,又稱為“紅黑樹”,它一種特殊的二叉查找...
    張晨輝Allen閱讀 9,331評論 5 30
  • 紅黑樹是平衡二叉查找樹的一種。為了深入理解紅黑樹,我們需要從二叉查找樹開始講起。 BST 二叉查找樹(Binary...
    kanehe閱讀 1,392評論 0 8
  • 一. 算法之變,結構為宗 計算機在很多情況下被應用于檢索數據,比如航空和鐵路運輸業的航班信息和列車時刻表的查詢,都...
    Leesper閱讀 6,988評論 13 42
  • 1、紅黑樹介紹 紅黑樹又稱R-B Tree,全稱是Red-Black Tree,它是一種特殊的二叉查找樹,紅黑樹的...
    文哥的學習日記閱讀 9,901評論 1 35
  • 尋找紅黑樹的操作手冊 前言 二叉樹知識點回憶以及整理[http://www.lxweimin.com/p/bd3c...
    靜默加載閱讀 684評論 0 1