1. 程式人生 > 實用技巧 >紅黑樹原理(插入+刪除過程分析)

紅黑樹原理(插入+刪除過程分析)

引言
紅黑樹的原理經常在面試中被問到,因此根據瀏覽的一些部落格進行了歸納總結。
參考如下:新增連結描述新增連結描述新增連結描述
紅黑樹原理

  1. 為什麼會有樹這種結構
    最初的資料結構是從線性表開始,而線性表的邏輯結構屬於一對一的關係;而對於一對多的資料邏輯關係就需要利用樹結構來解決。
  2. 紅黑樹結構提出的意義
    紅黑樹是一種非線性的資料結構,其設計目的是為了高效地進行增刪改查。
    (1) 二叉查詢樹
    a) 二叉查詢樹的特點:
    左子樹上所有結點的值均小於或等於它的根結點的值;右子樹上所有結點的值均大於或等於它的根結點的值。
    在這裡插入圖片描述

b) 二叉查詢樹的刪除過程
按照待刪除節點的位置,分為以下四種情況:

  1. 要刪除的節點沒有左右孩子

    直接刪除

  2. 要刪除的節點只有左孩子
    如果要刪除的節點只有左孩子,那麼就讓該節點的父親結點指向該節點的左孩子,然後刪除該節點。
    在這裡插入圖片描述

  3. 要刪除的節點只有右孩子
    如果要刪除的節點只有右孩子,那麼就讓該節點的父親結點指向該節點的右孩子,然後刪除該節點。
    在這裡插入圖片描述

對於上面這兩種情況我們還應該在之前進行一個判斷,就是判斷這個節點是否是根節點,如果是根節點的話,就直接讓根節點指向這個節點的左孩子或右孩子,然後刪除這個節點。
4) 要刪除的節點有左右孩子
 找到該節點的右子樹中的最左孩子
 將此左孩子的值和待刪除的節點的值進行交換
 刪除此節點
在這裡插入圖片描述

c) 二叉查詢樹的查詢過程:
先與根節點比較,比根節點大則從右子樹查詢,比根節點小則從左子樹查詢,然後重複上述過程,直到找到目標元素或到葉子結點(沒有子結點)後仍未找到,則停止。

d) 二叉查詢樹的缺點:
若以9為根節點,然後依次插入13、15、17、19。會發生如下情況:
二叉查詢樹失去平衡,查詢效率降低。因此,未解決此問題,提出了平衡二叉樹的概念。
在這裡插入圖片描述

(2) 平衡二叉樹(AVL樹)
a) 平衡二叉樹的特點:
從任何一個節點出發,左右子樹深度之差的絕對值不超過1;左右子樹仍然為平衡二叉樹。
在這裡插入圖片描述

b) 平衡二叉樹的自平衡調整:
在平衡二叉樹中插入一個元素4,此時平衡二叉樹將自動進行平衡調整,即:
在這裡插入圖片描述

由於插入了4之後破壞了平衡,因此進行平衡糾正,即:
在這裡插入圖片描述

c) 平衡二叉樹的優點:
平衡二叉樹在插入時最多隻需要兩次旋轉就會重新恢復平衡;
查詢時既有著二叉查詢樹的優越性,在插入時還能通過調整繼續保持平衡特性

d) 平衡二叉樹的缺點:
刪除:平衡二叉樹最壞情況下需要維護被刪除節點到根節點路徑上所有節點的 ,旋轉的量級是O(logN);但紅黑樹只需要旋轉三次即可重新平衡,旋轉的量級是O(1)。
保持平衡:平衡二叉樹高度平衡,因此在大量插入和刪除節點的場景下,平衡二叉樹為了保持平衡需要調整的頻率會更高。
e) 選用條件:
在大量查詢情況下,平衡二叉樹效率更高;
在大量增刪的情況下,紅黑樹是首選
(3) 紅黑樹(RBT樹)
a) 結構特點:
每個節點都是紅色或者黑色;
樹的根始終是黑色的;
沒有兩個相鄰的紅色節點;
從節點到其任何後代NULL節點(葉子結點下方的兩個空節點,預設為黑色)的每條路徑都具有相同數量的黑色節點;
在這裡插入圖片描述

b) 紅黑樹的兩大操作:
 recolor(重新標記黑色或紅色)
 rotation(旋轉,使得樹保持平衡)
c) 紅黑樹的插入操作
設插入的節點為X

  1. 將新插入的節點標記為紅色
  2. 如果X是根節點(root),則標記為黑色
  3. 如果X的parent不是黑色,同時X也不是root
    3.1 如果X的uncle是紅色
    3.1.1 將parent和uncle標記為黑色
    3.1.2 將grand parent標記為紅色
    3.1.3 讓X節點的顏色與X祖父的顏色相同,然後重複步驟2、3
    如下:
    在這裡插入圖片描述

插入步驟如下:
a) 將新插入的X節點標記為紅色
b) 發現X的parent為紅色,且X的uncle為紅色
c) 將P和U標記為黑色
d) 將X及其grand parent標記為相同顏色(紅色),重複步驟2、3
e) 判斷grand parent是否為根節點,為根節點則標記為黑色
f) 結束插入
3.2 如果X的uncle是黑色,則分為四種情況進行處理
3.2.1 左左(P是G的左孩子,X是P的左孩子)
在這裡插入圖片描述

3.2.2 左右(P是G的左孩子,X是P的右孩子)
在這裡插入圖片描述

3.2.3 右右(P是G的右孩子,X是P的右孩子)
在這裡插入圖片描述

3.2.4 右左(P是G的右孩子,X是P的左孩子)
在這裡插入圖片描述

總結:在插入過程中,若節點值位置發生變化,則需要重新根據插入原則判斷是否影響了紅黑樹的特性,並根據插入後的步驟進行變換。
在這裡插入圖片描述

d) 紅黑樹的刪除操作
葉子節點:節點後無子節點
後繼節點:比其大的節點中的最小值(節點右子樹中的最小值)

  1. 刪除節點為紅色節點
    1.1 刪除紅色的葉子節點
    直接刪除。
    1.2 刪除紅色的非葉子節點
    需要找到被刪除節點的直接後繼,用它的值取代被刪除節點的值,然後按情況1刪除。
  2. 刪除節點為黑色節點
    2.1 刪除黑色的葉子節點
    2.1.1 待刪除節點D的兄弟節點S為紅色
    ①D為左節點
    在這裡插入圖片描述

將父親節點和兄弟節點的顏色互換,也就是p變成紅色,S變成黑色,然後將P樹進行AVL樹種的RR型操作,結果如下圖:
在這裡插入圖片描述

此時D的兄弟節點變為黑色,變成後續2.1.4討論 。
即:將父親節點P改成黑色,將兄弟節點S改成紅色,然後刪除D即可。
②D為右節點
在這裡插入圖片描述

將P和S的顏色互換,也就是將P變成紅色,將S變成黑色,然後對P進行類似AVL樹的LL操作。結果如下圖:
在這裡插入圖片描述

此時D的兄弟節點變為黑色,變成後續2.1.4討論 。
即:將父親節點P改成黑色,將兄弟節點S改成紅色,然後刪除D即可。
2.1.2 待刪除節點D的兄弟節點S為黑色,且遠侄子節點為紅色
① D為左孩子時,其遠侄子為S的右孩子
在這裡插入圖片描述

沒有上色的節點表示黑色紅色均可,注意如果SL為黑色,則SL必為NULL節點。
將P和S的顏色對調,然後對P樹進行類似AVL樹RR型的操作,最後把SR節點變成黑色,並刪除D即可。
在這裡插入圖片描述

② D為右孩子時,其遠侄子為S的左孩子
在這裡插入圖片描述

同樣,將P和S的顏色對調,然後再對P樹進行類似AVL樹LL型的操作,最後將SR變成黑色,並刪掉D即可。結果如下圖:
在這裡插入圖片描述

2.1.3 待刪除節點D的兄弟節點S為黑色,且近侄子節點為紅色
① D為左孩子時,其近侄子為S的左孩子
在這裡插入圖片描述

將SL右旋,並將S和SL的顏色互換,得到:
在這裡插入圖片描述

對SL進行LL變換,將P的顏色變為與S相同,刪掉D節點即可。
② D為右孩子時,其近侄子為S的右孩子
在這裡插入圖片描述

將S和SR顏色對調,然後對SR進行左旋操作,結果如下圖:
在這裡插入圖片描述

對SL進行RR變換,將P的顏色變為與S相同,刪掉D節點即可。
2.1.4 父親節點P為紅色,兄弟節點和兄弟節點的兩個孩子(只能是NULL節點)都為黑色情況。
在這裡插入圖片描述

將父親節點P改成黑色,將兄弟節點S改成紅色,然後刪除D即可。如下圖:
在這裡插入圖片描述

2.1.5 父親節點P,兄弟節點和兄弟節點的兩個孩子(只能是NULL節點)都為黑色情況。
在這裡插入圖片描述

將兄弟節點S的顏色改成紅色,這樣刪除D後P的左右兩支的黑節點數就相等了,但是經過P的路徑上的黑色節點數會少1,這個時候,再以P為起始點,繼續根據情況進行平衡操作結果如下圖:

在這裡插入圖片描述