和AVL樹一樣,紅黑樹也是一種自平衡二叉排序樹,其定義如下:
(1)節點有且只有兩種顏色,紅色和黑色。
(2)根節點和葉子節點必須是黑色,其中,葉子節點是虛擬存在的空節點(NULL)。
(3)紅色節點的兩個子節點必須是黑色。
(4)任意節點到葉子節點的路徑上,必須包含相同數目的黑色節點。
從紅黑樹的定義可以發現,任意節點左右子樹的高度差在一倍之內(最長路徑為節點紅黑相間,最短路徑為節點全黑)。
由於紅黑樹對平衡性的要求沒有AVL樹高,因此頻繁插入和刪除節點時,觸發平衡調整的次數更少,平衡調整的過程也更易收斂。
1. 插入節點
新插入節點x,x.color = RED,未違背定義(1)(2)(4),可能違背定義(3)。
若根節點ROOT== NULL,則ROOT= x,ROOT.color = BLACK,RETURN。
LOOP:
(1)若當前節點x == ROOT,則ROOT.color = BLACK,RETURN。
(2)若父節點px = x.parent,px.color == BLACK,則未違背定義(3),RETURN。
(3)爺爺節點ppx = px.parent(ppx一定為黑色)。假設px為ppx的左孩子(px為右孩子的情況同理),則叔叔節點ux = ppx.right:
(特殊情況一)ux為黑色,x為px的左孩子

px.color = BLACK,ppx.color = RED,再以ppx為支點右旋,回到LOOP(到(2)時RETURN)。
(情況二)ux為黑色,x為px的右孩子

以px為支點左旋,當前節點x = px,進入(特殊情況一)。
(情況三)ux為紅色

px.color = BLACK,ux.color = BLACK,ppx.color = RED,當前節點x = ppx,回到LOOP。
2. 刪除節點
若被刪除節點m的左右子樹非空,則將左子樹的最大節點(或右子樹的最小節點)n的數據保存到節點m上,再刪除節點n。
若n.color == RED,則未違背定義(1)(2)(3)(4),RETURN。
若n.color == BLACK,則未違背定義(1)(2),可能違背定義(3)(4)。設節點n的孩子節點為x:
(1)若n.parent == NULL(即n == ROOT),且x == NULL,則說明n為唯一節點,未違背定義(3)(4),RETURN。
(2)若n.parent == NULL(即n == ROOT),且x != NULL,則說明x將為根節點,ROOT = x。
(3)若n.parent != NULL,且x == NULL,則x = n,待平衡調整完畢后再刪除x。
(4)若n.parent != NULL,且x != NULL,則刪除節點n,節點n的孩子節點x替到n的位置。
LOOP:
(1)若當前節點x == ROOT,則x.color = BLACK,RETURN。
(2)若x.color == RED,則x.color = BLACK,RETURN。
(3)父節點px = x.parent,假設x為px的左孩子(x為右孩子的情況同理),則兄弟節點sx = px.right:
(特殊情況一)sx為黑色,sx的右孩子srx為紅色

sx.color = px.color,px.color = BLACK,srx.color = BLACK,再以px為支點左旋,x = ROOT,回到LOOP(到(1)時RETURN)。
(情況二)sx為黑色,sx的右孩子srx為黑色,sx的左孩子slx為紅色

slx.color = BLACK,sx.color = RED,再以sx為支點右旋,進入(特殊情況一)。
(情況三)sx為黑色,sx的右孩子srx為黑色,sx的左孩子slx為黑色

sx.color = RED,當前節點x = px,回到LOOP。
(情況四)sx為紅色(px一定為黑色,sx的兩個孩子節點一定為黑色)

px.color = RED,sx.color = BLACK,再以px為支點左旋,進入(特殊情況一)或(情況二)或(情況三)。
