红黑树 - 一种自平衡的二叉查找树
性质
- 节点是红色或黑色。
- 根节点是黑色。
- 每个叶子节点都是黑色的空节点(NIL节点)。
- 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
这些规则的限制保证了红黑树自平衡,从根到叶子的最长路径不会超过最短路径的2倍。
插入
1.向原红黑树插入值为14的新节点
满足性质不需要调整
2.向原红黑树插入值为21的新节点
由于父节点22是红色节点,因此这种情况打破了红黑树的规则4(每个红色节点的两个子节点都是黑色),必须进行调整,使之重新符合红黑树的规则。
调整
变色
为了重新符合红黑树的规则,尝试把红色节点变为黑色,或者把黑色节点变为红色。
- 下图所表示的是红黑树的一部分,需要注意节点25并非根节点。因为节点21和节点22连续出现了红色,不符合规则4,所以把节点22从红色变成黑色:
- 但这样并不算完,因为凭空多出的黑色节点打破了规则5,所以发生连锁反应,需要继续把节点25从黑色变成红色:
- 此时仍然没有结束,因为节点25和节点27又形成了两个连续的红色节点,需要继续把节点27从红色变成黑色:
此时可以说变色才告一段落。
旋转
左旋右旋对于学过数据结构平衡二叉树的同学不会感到陌生。
左旋转
以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。
逆时针旋转红黑树的两个节点,使得父节点被自己的右孩子取代,而自己成为自己的左孩子。如下图。
上图中,身为右孩子的Y取代了X的位置,而X变成了自己的左孩子。此为左旋转。
右旋转
以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。
顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己的右孩子。
上图中,身为左孩子的Y取代了X的位置,而X变成了自己的右孩子。
变色与旋转要根据插入和删除时的具体情况具体分析,以上述插入21节点为例
以插入21节点为例
第一步
变色,把节点25及其下方的节点变色:
此时节点17和节点25是连续的两个红色节点,那么把节点17变成黑色节点?
恐怕不合适。这样一来不但打破了规则4,而且根据规则2(根节点是黑色),也不可能把节点13变成红色节点。
第二步
变色已无法解决问题,我们把节点13看做X,把节点17看做Y,像刚才的示意图那样进行左旋转
左旋转为下图
由于根节点必须是黑色节点,所以需要变色。
第三步
这样并没有结束,因为其中两条路径(17 -> 8 -> 6 -> NIL)
的黑色节点个数是4,其他路径的黑色节点个数是3,不符合规则5。
这时候我们需要把节点13看做X,节点8看做Y,进行右旋转
第四步
↓
↓
最后根据规则变色
第五步
至此便完成了插入操作,本插入过程属于复杂的一种情况,其他情况需要具体分析。
删除
红黑树的删除有许多种情况需要根据不同规则进行操作,下面举出部分例子。
情形分析
一、从树中删除节点X(以寻找后继节点的方式进行删除)
- 情况①:如果X没有孩子,且如果X是红色,直接删除X;如果X是黑色,则以X为当前节点进行旋转调色,最后删掉X
- 情况②:如果X只有一个孩子C,交换X和C的数值,再对新X进行删除。根据红黑树特性,此时X不可能为红色,因为红色节点要么没有孩子,要么有两个黑孩子。此时以新X为当前节点进行情况①的判断
- 情况③:如果X有两个孩子,则从后继中找到最小节点D,交换X和D的数值,再对新X进行删除。此时以新X为当前节点进行情况①或②的判断
二、旋转调色
(N=旋转调色的当前节点[等于情况①中的X],P=N的父亲,W=N的兄弟,Nf=N的远侄子,Nn=N的近侄子)
- 情况1:N是根或者N是红色,则:直接将N设为黑色
- 情况2:N不是根且N是黑色,且W为红色,则:将W设为黑色,P设为红色,对P进行旋转(N为P的左子时进行左旋,N为P的右子时进行右旋),将情况转化为情况1、2、3、4、5
- 情况3:N不是根且N是黑色,且W为黑色,且W的左右子均为黑色,则:将W设为红色,将P设为当前节点进行旋转调色,将情况转化为情况1、2、3、4、5
- 情况4:N不是根且N是黑色,且W为黑色,且Nf为黑色,Nn为红色,则:交换W与Nn的颜色,并对W进行旋转(N为P的左子进行右旋,N为P的右子进行左旋),旋转后N的新兄弟W有一个红色WR,则转换为情况5
- 情况5:N不是根且N是黑色,且W为黑色,且Nf为红色,Nn为黑色,则:将W设为P的颜色,P和Nf设为黑色,并对P进行旋转(N为P的左子进行左旋,N为P的右子进行右旋),N设为根
删除示例
(1)删除12
(2)删除1
(3)删除9
(4)删除2
(5)删除0
(6)删除11
(7)删除7
(8)删除19
(9)删除4
(10)删除15
(11)删除18
(12)删除5
(13)删除14
(14)删除13
(15)删除10
(16)删除16
(17)删除6
(18)删除3
(19)删除8