紅黑樹
紅黑樹基於二叉查詢樹的附加特性
- 節點是紅色或黑色。
- 根節點是黑色。
- 每個葉子節點都是黑色的空節點(葉子結點指為空的葉子結點)。
- 每個紅色節點的兩個子節點都是黑色的(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)。
- 從任意節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
1. 資料結構
class TreeNode{
private Boolean color;
private int val;
private TreeNode left;
private TreeNode right;
private TreeNode parent;
get,set...
}
class RBTree{
public boolean add(int val){...}
public boolean delete(int val){...}
public void display(){...}
}
2. 左旋以及右旋
2.1 左旋
2.2 右旋
3. 插入
-
新插入的節點(newNode)為紅色。
-
按照二分查詢樹插入規則插入。
-
分情況討論(以下情況基本都是為了保持上文所講的的紅黑樹特性4和特5)
1、若newNode為根節點,則變為黑色,插入完畢,返回 true。
2、若newNode父節點為黑色,則插入完畢,返回 true。
3、如下圖所示,若newNode父節點為紅色,且叔叔節點存在且為紅色,則父節點與叔叔節點變為黑色,祖父節點變為紅色,newNode = 祖父節點。
4、如下圖所示,若newNode父節點為紅色,叔叔節點不存在或為黑色,且newNode為父節點右孩子,父節點為祖父節點左孩子,則以父節點為軸左旋,進入情況6.
5、如下圖所示,若newNode父節點為紅色,叔叔節點不存在或為黑色,且newNode為父節點左孩子,父節點為祖父節點右孩子,則以父節點為軸右旋,進入情況7
6、如下圖,此時以祖父節點為軸進行右旋,將祖父節點變為紅色,newNode變為黑色。
7、如下圖,此時以祖父節點為軸進行左旋,將祖父節點變為紅色,newNode變為黑色。
4. 刪除
分情況討論(和插入一樣,以下情況基本都是為了保持上文所講的的紅黑樹特性4和特5)
- 如下圖,如果待刪除節點B有兩個非空的孩子節點,轉化成待刪除節點只有右孩子(或沒有孩子)的情況,習慣性選取待刪除節點右子樹最小節點E替換待刪除節點(只是值替換,顏色不變),並將待刪除節點變為E。
-
根據待刪除節點和唯一子節點顏色,分情況處理:
-
自身O是紅色,子節點N是黑色,直接刪除。
-
自身O是黑色,子節點N是紅色,直接刪除並將子節點N變為黑色。
-
自身O是黑色,子節點N不存在(不存在即子節點為空黑色節點,也可以用來判斷)或也是黑色,較為複雜,先刪除,再分情況討論:
1、N是根節點,則不需要調整。
2、如下圖,N的父親、兄弟、侄子都是黑色,則將兄弟變為紅色,父親視作N,進行遞迴處理。
-
3、(存在映象)N的兄弟節點是紅色,且N為父親節點左兒子,則以父親節點為軸左旋(否則右旋),並將旋轉後N的祖父節點變為黑色,N的父節點變為紅色,進入情況4,5或6.
4、N的父親節點是紅色,兄弟和侄子節點是黑色,父親節點變為黑色,兄弟節點變為紅色。
5、(存在映象)N的父節點顏色隨意,兄弟節點為父節點黑色右孩子,左侄子節點為紅色,右侄子節點為黑色,以兄弟節點為軸進行右旋,將旋轉後N的兄弟節點變為黑色,N的右侄子節點變為紅色,進入情況6
6、(存在映象)N的父節點隨意,兄弟節點為父節點的黑色右兒子,右侄子節點為紅色,以N的父節點為軸進行左旋,左旋後的N的祖父節點變為父節點顏色,父節點變黑,叔叔節點變黑。