紅黑樹的原理以及實現

紅黑樹

紅黑樹基於二叉查找樹的附加特性

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

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)爲紅色。java

  • 按照二分查找樹插入規則插入。git

  • 分狀況討論如下狀況基本都是爲了保持上文所講的的紅黑樹特性4和特5github

    一、若newNode爲根節點,則變爲黑色,插入完畢,返回 true。數據結構

    二、若newNode父節點爲黑色,則插入完畢,返回 true。測試

    三、以下圖所示,若newNode父節點爲紅色,且叔叔節點存在且爲紅色,則父節點與叔叔節點變爲黑色,祖父節點變爲紅色,newNode = 祖父節點。3d

    四、以下圖所示,若newNode父節點爲紅色,叔叔節點不存在或爲黑色,且newNode爲父節點右孩子,父節點爲祖父節點左孩子,則以父節點爲軸左旋,進入狀況6.code

五、以下圖所示,若newNode父節點爲紅色,叔叔節點不存在或爲黑色,且newNode爲父節點左孩子,父節點爲祖父節點右孩子,則以父節點爲軸右旋,進入狀況7blog

六、以下圖,此時以祖父節點爲軸進行右旋,將祖父節點變爲紅色,newNode變爲黑色。遞歸

七、以下圖,此時以祖父節點爲軸進行左旋,將祖父節點變爲紅色,newNode變爲黑色。get

4. 刪除

分狀況討論(和插入同樣,如下狀況基本都是爲了保持上文所講的的紅黑樹特性4和特5)

  1. 以下圖,若是待刪除節點B有兩個非空的孩子節點,轉化成待刪除節點只有右孩子(或沒有孩子)的狀況,習慣性選取待刪除節點右子樹最小節點E替換待刪除節點(只是值替換,顏色不變),並將待刪除節點變爲E。

  1. 根據待刪除節點和惟一子節點顏色,分狀況處理:

    1. 自身O是紅色,子節點N是黑色,直接刪除。

    2. 自身O是黑色,子節點N是紅色,直接刪除將子節點N變爲黑色。

    3. 自身O是黑色,子節點N不存在(不存在即子節點爲空黑色節點,也能夠用來判斷)也是黑色,較爲複雜,先刪除,再分狀況討論:

      一、N是根節點,則不須要調整。

      二、以下圖,N的父親、兄弟、侄子都是黑色,則將兄弟變爲紅色,父親視做N,進行遞歸處理。

三、(存在鏡像)N的兄弟節點是紅色,且N爲父親節點左兒子,則以父親節點爲軸左旋(不然右旋),並將旋轉後N的祖父節點變爲黑色,N的父節點變爲紅色,進入狀況4,5或6.

四、N的父親節點是紅色,兄弟和侄子節點是黑色,父親節點變爲黑色,兄弟節點變爲紅色。

​ 五、(存在鏡像)N的父節點顏色隨意,兄弟節點爲父節點黑色右孩子,左侄子節點爲紅色,右侄子節點爲黑色,以兄弟節點爲軸進行右旋,將旋轉後N的兄弟節點變爲黑色,N的右侄子節點變爲紅色,進入狀況6

​ 六、(存在鏡像)N的父節點隨意,兄弟節點爲父節點的黑色右兒子,右侄子節點爲紅色,以N的父節點爲軸進行左旋,左旋後的N的祖父節點變爲父節點顏色,父節點變黑,叔叔節點變黑。

測試

原樹(上右下左)

刪除53

刪除23

刪除54

添加67

代碼:

https://github.com/DEUSJIN/RBTree

相關文章
相關標籤/搜索