邓俊辉数据结构学习-8-3-红黑树
Posted patientcat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了邓俊辉数据结构学习-8-3-红黑树相关的知识,希望对你有一定的参考价值。
红黑树
动机
Q: 在已经有了AVL之类的BBST,为什么还需要引入红黑树?
A: 我们希望数据结构具有关联性,即相邻版本之间,比如说第一次插入,和第二次插入时,树的结构不能发生太大变化,
应该可以经过O(1)次数就可以变化完成。
对于AVL树来说,插入是满足这个条件的,删除却不满足这个条件。
红黑树就满足这一特性,插入和删除操作后的拓扑变化不会超过O(1)。
定义
前提:给红黑树添加外部节点,保证为真二叉树
- 树根:必为黑色,即帽子是黑色
- 外部节点:必为黑色,即靴子为黑色
- 其余节点:若为红节点,则只能有黑色孩子
- 红之子,之父必须为黑色
- 外部节点到根:途中黑节点数目相等
- 所有外部节点到根经过的黑色节点数目相同,用来控制平衡
直观解释:
提升变换后(即每一个红色节点和它的父亲平齐)
所有底层节点处于同一水平高度。
红黑树就变换成一颗2-4树,我们将红黑树的每个黑色节点和提升后的红色节点(可能没有)看做B树的一个Super节点
红黑树就完全等价于一颗B树,而且可以看到的是,因为红黑树所有外部节点到根的经过的黑色数目相同,在B树中,则
更加能体现这一特征
实现
比较重要的差别在于红黑树的高度叫做黑高度,即只计算黑色节点的高度
int updateHeight(BinNodePos(T))
{
//原来的高度计算方法,但现在只计算黑色节点x->height = max(x->lc->height, x->rc->height) + 1 ;
x->height = max(x->lc->height, x->rc->height);
if(IsBlack(x))
++x->height;
return x->height;
}
插入
tips 借助B树理解红黑树
理解:
在不失一般性的情况下插入一个新节点e,我们将其染为红色。目的是尽可能的满足红黑树的4条性质。可以看到
1,2,4都满足。但是3不一定。因此e的父亲可能是黑色可能是红色。如果是黑色,插入成功返回即可。如果是红色的话
此时我们就需要解决双红冲突的问题了。
双红冲突--黑色叔父
前提:当新插入节点的e的父亲为红色时,其父亲必然不是根节点,且其祖父节点必然是黑色,否则其父节点也不可能是
红色。
此时我们观察其叔父节点
情形1:
当被删除节点的兄弟为黑色的时候{:.warning}
我们不难发现
- B树变换:借助B树的影子进行理解,当叔父节点为黑色时,相当于发生了这样一种情况。整个Super节点变为了
RRB的情形,此时在B树中,我们只要将其重新染为RBR的颜色即可。 - RB树变换:直接利用3+4重构的方式,依照B树染色后的图进行构造就可以得到调整后的RB树变换
node g
┌───┐
┌ ─ ─ ─│███│────┐
└───┘ │ node p
▼ ▼ ┌───┐
node p .─. node u┌───┐ ┌ ─ ─ ─│███│─ ─ ─ ─ ┐
┌ ─ ─ ─(red)─────┐ │███│ └───┘
`─‘ │ ├───┤ ▼ ▼
▼ ▼ │***│ node e .─. node g.─.
node e .─. ┌───┐ │***│ ───? ┌────(red)────┐ ┌─(red)──┐
┌────(red)────┐ │███│ │***│ │ `─‘ │ │ `─‘ │
│ `─‘ │ ├───┤ └───┘ ▼ ▼ ▼ node u ▼
▼ ▼ │***│ ┌───┐ ┌───┐ ┌───┐ ┌───┐
┌───┐ ┌───┐ │***│ │███│ │███│ │███│ │███│
│███│ │███│ │***│ ├───┤ ├───┤ ├───┤ ├───┤
├───┤ ├───┤ └───┘ │***│ │***│ │***│ │***│
│***│ │***│ ┌───────────────────┐ │***│ │***│ │***│ │***│
│***│ │***│ │ directRB change │ │***│ │***│ │***│ │***│
│***│ │***│ └───────────────────┘ └───┘ └───┘ └───┘ └───┘
└───┘ ║ └───┘ ▲
║ ║
║ ║
▼ ║
node e node p node g node e node p node g
.─. .─. ┌───┐ ┌─────────────────────┐ .─. ┌───┐ .─.
┌────(red│(red)││███│───┐ │ indirectBT change │ ┌────(red││███││(red)───┐
│ `─‘│ `─‘ │└───┘ │ └─────────────────────┘ │ `─‘│└───┘│ `─‘ │
│ │ │ │ ══════════════════? │ │ │ │
▼ ▼ ▼ node u▼ ▼ ▼ ▼ node u▼
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐
│███│ │███│ │███│ │███│ │███│ │███│ │███│ │███│
├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘
同理,对于zag-zig的情形处理类似依然使用简单的3+4重构方式处理就可以了,还有另外俩种对称形式类似。
node g
┌───┐ ┌───────────────────┐
─ ─ ─ ─ ─ ─│███│────┐ │ directRB change │
│ └───┘ │ └───────────────────┘ node e
▼ ▼ ┌───┐
node p node u┌───┐ ┌ ─ ─ ─│███│─ ─ ─ ─ ┐
┌───(red)─ ─ ─ │███│ └───┘
│ `─‘ │ ├───┤ ▼ ▼
│ ▼ │***│ node p .─. node g.─.
│ node e─. │T3*│ ───? ┌────(red)───┐ ┌─ (red)────┐
▼ ┌─(red)─┐ │***│ │ `─‘ │ │ `─‘ │
┌───┐ │ `─‘ │ └───┘ ▼ ▼ ▼ node u ▼
│███│ ▼ ▼ ┌───┐ ┌───┐ ┌───┐ ┌───┐
├───┤ ┌───┐ ┌───┐ │███│ │███│ │███│ │███│
│***│ │███│ │███│ ├───┤ ├───┤ ├───┤ ├───┤
│T0*│ ├───┤ ├───┤ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │T0*│ │T1*│ │T2*│ │T3*│
└───┘ │T1*│ │T2*│ │***│ │***│ │***│ │***│
│***│ │***│ └───┘ └───┘ └───┘ └───┘
║ └───┘ └───┘ ▲
║ ║
║ ║
▼ ║
node p node e node g node p node e node g
.─. .─. ┌───┐ ┌─────────────────────┐ .─. ┌───┐ .─.
┌────(red│(red)││███│───┐ │ indirectBT change │ ┌────(red││███││(red)───┐
│ `─‘│ `─‘ │└───┘ │ └─────────────────────┘ │ `─‘│└───┘│ `─‘ │
│ │ │ │ ══════════════════? │ │ │ │
▼ ▼ ▼ node u▼ ▼ ▼ ▼ node u▼
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐
│███│ │███│ │███│ │███│ │███│ │███│ │███│ │███│
├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
│T0*│ │T1*│ │T2*│ │T3*│ │T0*│ │T1*│ │T2*│ │T3*│
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘
双红冲突--红色叔父
此时我们观察其叔父节点
情形2:当叔父节点为红色的时候
就会变成RRBR的形式,此时节点发生上溢出。在B树中我们采取的方式是分裂。
- B树变换:在B树中,我们要将中位节点上溢,从而保证B树的合理性。
- RB树变换:在RB树中,我们仅仅是做了提升变换将其变为B树,所以实际上只需要改变颜色,就可以对其B树的
影子完成分层,从而完成RB树变换- 在红黑树种,只要将一个树的颜色染为红色,就相当于在B树的影子中让其向上一层
- 染为黑色,则代表这就是B树的影子中的某一层
- 简单结论就是:在B树中的影子处于同一层的红黑树节点,黑色的节点高度必须必红色的节点高
nodeG nodeG ┌───┐ .─. ┌ ─ ─ ─ ─ ─│███│─ ─ ─ ┌──────────(red)─────┐ └───┘ │ │ `─‘ │ ▼ ▼ ▼ ▼ nodeP .─. nodeU .─. nodeP┌───┐ nodeU┌───┐ ┌────(red)─ ─ ┌──(red)─┐ ┌────│███│─ ─ ┌──│███│─┐ │ `─‘ │ │ `─‘ │ │ └───┘ │ │ └───┘ │ │ ▼ ▼ ▼ ───────────? │ ▼ ▼ ▼ ▼ nodeE .─. ┌───┐ ┌───┐ ▼ nodeE .─. ┌───┐ ┌───┐ ┌───┐ ┌─(red)─┐ │███│ │███│ ┌───┐ ┌─(red)─┐ │███│ │███│ │███│ │ `─‘ │ ├───┤ ├───┤ │███│ │ `─‘ │ ├───┤ ├───┤ ├───┤ ▼ ▼ │***│ │***│ ├───┤ ▼ ▼ │***│ │***│ │***│ ┌───┐ ┌───┐ │***│ │***│ │***│ ┌───┐ ┌───┐ │***│ │***│ │***│ │███│ │███│ │***│ │***│ │***│ │███│ │███│ │***│ │***│ │***│ ├───┤ ├───┤ └───┘ └───┘ │***│ ├───┤ ├───┤ └───┘ └───┘ └───┘ │***│ │***│ └───┘ │***│ │***│ ▲ │***│ │***│ ┌───────────────────┐ │***│ │***│ ║ │***│ │***│ │ directRB change │ │***│ │***│ ║ ║ └───┘ └───┘ └───────────────────┘ └───┘ └───┘ ║ ║ ║ nodeG ▼ ┌───┐ .─. ┌───┐ ┌─────┤???├─(red)─┤???├──┐ │ └───┘ `─‘ └───┘ │ nodeP nodeE nodeG nodeU ▼ ▼ .─. .─. ┌───┐ .─. ┌─────────────────────┐ nodeP nodeE nodeU ┌────(red│(red)││███││(red)───┐ │ indirectBT change │ ┌───┐ .─. ┌───┐ │ `─‘│ `─‘ │└───┘│ `─‘ │ └─────────────────────┘ ┌─│███│ │(red)──┐ ┌──│███│─┐ │ │ │ │ │ ══════════════════? │ └───┘ │ `─‘ │ │ └───┘ │ ▼ ▼ ▼ ▼ ▼ │ │ │ │ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ▼ ▼ ▼ ▼ ▼ │███│ │███│ │███│ │███│ │███│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ │███│ │███│ │███│ │███│ │███│ │***│ │***│ │***│ │***│ │***│ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ └───┘ └───┘ └───┘ └───┘ └───┘ │***│ │***│ │***│ │***│ │***│ └───┘ └───┘ └───┘ └───┘ └───┘ 这里有个中间的染色步骤,此时P,E构成新节点,他们都是红色,但是P的高度要高于E,所以讲P染成黑色。 而U是红色,U要成为新的B树节点,所以必须保证这个节点里有一个黑色,所以将U染为黑色。
相应的zigzig变化过程
nodeG nodeG ┌───┐ .─. ┌ ─ ─ ─ ─ ─│███│─ ─ ─ ┌──────────(red)─────┐ └───┘ │ │ `─‘ │ ▼ ▼ ▼ ▼ nodeP .─. nodeU .─. ┌───┐ nodeP nodeU┌───┐ ┌ ─ ─(red)────┐ ┌──(red)─┐ ┌ ─│███│─────┐ ┌──│███│─┐ `─‘ │ │ `─‘ │ └───┘ │ │ └───┘ │ ▼ │ ▼ ▼ ───────────? ▼ │ ▼ ▼ nodeE .─. ▼ ┌───┐ ┌───┐ nodeE .─. ▼ ┌───┐ ┌───┐ ┌─(red)──┐ ┌───┐ │███│ │███│ ┌─(red)─┐ ┌───┐ │███│ │███│ │ `─‘ │ │███│ ├───┤ ├───┤ │ `─‘ │ │███│ ├───┤ ├───┤ ▼ ▼ ├───┤ │***│ │***│ ▼ ▼ ├───┤ │***│ │***│ ┌───┐ ┌───┐ │***│ │***│ │***│ ┌───┐ ┌───┐ │***│ │***│ │***│ │███│ │███│ │***│ │***│ │***│ │███│ │███│ │***│ │***│ │***│ ├───┤ ├───┤ │***│ └───┘ └───┘ ├───┤ ├───┤ │***│ └───┘ └───┘ │***│ │***│ └───┘ │***│ │***│ └───┘ ▲ │***│ │***│ ┌───────────────────┤***│ │***│ ║ │***│ │***│ │ directRB change │***│ │***│ ║ └───┘ └╦──┘ └───────────────────┴───┘ └───┘ ║ ║ ║ nodeG ▼ ┌───┐ .─. ┌───┐ ┌─────┤???├─(red)─┤???├──┐ │ └───┘ `─‘ └───┘ │ nodeE nodeP nodeG nodeU ▼ ▼ .─. .─. ┌───┐ .─. ┌─────────────────────┐ nodeE nodeP nodeU ┌────(red│(red)││███││(red)───┐ │ indirectBT change │ .─. ┌───┐ ┌───┐ │ `─‘│ `─‘ │└───┘│ `─‘ │ └─────────────────────┘ ┌─(red)─┬─┤███├─┐ ┌──│███│─┐ │ │ │ │ │ ══════════════════? │ `─‘ │ └───┘ │ │ └───┘ │ ▼ ▼ ▼ ▼ ▼ │ │ │ │ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ▼ ▼ ▼ ▼ ▼ │███│ │███│ │███│ │███│ │███│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ │███│ │███│ │███│ │███│ │███│ │***│ │***│ │***│ │***│ │***│ ├───┤ ├───┤ ├───┤ ├───┤ ├───┤ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│ └───┘ └───┘ └───┘ └───┘ └───┘ │***│ │***│ │***│ │***│ │***│ └───┘ └───┘ └───┘ └───┘ └───┘
总结
至此,红黑树的插入完毕,可以看到,插入总共需要进行俩种情况的处理。
- 第一种需要进行RB树的重构,但是,只需要一次就完成了红黑树的调整。
- 第二种虽然有可能递归logN次,但是,由于并不需要进行结构调整,仅仅是进行染色。所以依然认为其满足RB
树的特点
- 即在插入后,RB树的拓扑调整最多不超过O(1)次。
删除
平凡情况——删除节点或其后继有一个为红色
RB树的删除,我们依然先调用BST的removeAt算法。被删除节点会由其右孩子(有可能不存在)添补而上。
┌───┐ ┌───┐
p│███│ │███│
└─┬─┘ └─┬─┘ ┌────┐
│ │succ│
┌──────────┐ │ ┌────┐ │ └────┘
│deleteNode│─┐ ▼ │succ│ ▼ │
└──────────┘x└?.─. └────┘ ──────────? ┌───┐?──────┘
┌────(red)──────┐│ ┌────│███│────┐
▼ `─‘ ▼▼ ▼ └───┘ ▼
┌───┐ r┌───┐ ┌───┐ ┌───┐
w│nul│ ┌─┤███│ ──┐ rl│nul│ rr│???│
└───┘ │ └───┘ │ └───┘ └───┘
▼ ▼
┌───┐ ┌───┐
rl│nul│ rr│???│
└───┘ └───┘
我们认为被删除节点为红色,那么其左右孩子节点,父亲节点则一定为黑色。根据性质3。
首先要明白removeAt的语义,x节点最多只有一个孩子。在这里我们不妨认为其是r(r也有可能不存在,即也是外部节点)
那么另外一个孩子w则是外部节点,同样依然可以是对称的情况
当x被删除后,条件3不会受到任何影响,r接替x,rl和rr上的外部节点高度不受任何影响。理解为删除虚边之后,RB树
的节点不受影响。
按照B树的观点来理解,删除红色节点,对于Super节点不会有任何影响,因为Super节点的主要承担者是黑色节点
┌───┐ ┌───┐
│???│ │???│
└─┳─┘ └─┳─┘ ┌────┐
┃ ┃ │succ│
┌──────────┐ ┃ ┌────┐ ┃ └────┘
│deleteNode│─┐ ▼ │succ│ ▼ │
└──────────┘ └?┌───┐ └────┘ ──────────? ┌───┐?──────┘
┌────│███│─ ─ ─ ┐│ ┌────│███│────┐
▼ └───┘ ▼▼ ▼ └───┘ ▼
┌───┐ .─. ┌───┐ ┌───┐
│nul│ ─ ─(red) ─ ┐ │nul│ │???│
└───┘ │ `─‘ └───┘ └───┘
▼ ▼
┌───┐ ┌───┐
│nul│ │███│
└───┘ └───┘
同样依然理解为删除虚边之后,黑高度不受影响。
按照B树的观点来理解,删除黑色节点,B树的Super节点会少1,因此需要补充一个黑色节点。所以补充在原位置上的红色
节点被染黑。而消失一个红色节点却不影响这个B树的高度。
DoubleBlack
当俩个节点都为黑色的时候,删除一个必定会导致B树高度减少,从而不稳定。此时就分为4种情况。
情形1:
被删除节点的兄弟节点为黑色,且其有一个红色孩子,意思就是被删除节点X有一个红色的侄子,
则按照B树的观点来看,兄弟比较富裕,因此可以通过旋转的方式调整
按照RB树的观点来看,直接3+4重构即可,然后染色
nodeP
┌───┐ nodeS
┌ ─ ─ ─ ─ ─│???│─ ─ ─ ┌───┐
└───┘ │ ┌──────│???│──────┐
▼ ▼ │ └───┘ │
nodeS┌───┐ nodeX┌───┐ │ │
┌ ─ ─│███│────┐ │███│ │ │
└───┘ │ └─┬─┘ no▼eT no▼eP
▼ │ │ ───────────? ┌───┐ ┌───┐
nodeT .─. ▼ ▼ ┌───│███│───┐ ┌─│███│───┐
┌─(red)──┐ ┌───┐ ┌───┐ │ └───┘ │ │ └───┘ │
│ `─‘ │ │???│ nodeR│███│ │ │ │ │
▼ ▼ ├───┤ ├───┤ ▼ ▼ ▼ ▼
┌───┐ ┌───┐ │***│ │***│ ┌───┐ ┌───┐ ┌───┐ ┌───┐
│███│ │███│ │***│ │***│ │███│ │███│ │???│ │███│ nodeR/X
├───┤ ├───┤ │***│ │***│ ├───┤ ├───┤ ├───┤ ├───┤
│***│ │***│ └───┘ └───┘ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ ┌───────────────────┐ │***│ │***│ │***│ │***│
└───┘ └───┘ │ directRB change │ └───┘ └───┘ └───┘ └───┘
║ └───────────────────┘ ▲
║ ║
▼ ║
nodeP nodeS
┌───┐ ┌───┐
┌─────│???│────┐ ┌──────│???│──────┐
│ └───┘ │ │ └───┘ │
│ │ │ │
│ │ ┌─────────────────────┐ │ │
▼ │ │ indirectBT change │ no▼eT no▼eP
nodeT nodeS nodeX └─────────────────────┘ ┌───┐ ┌───┐
.─. ┌───┐ ┌┐ ══════════════════? ┌───│███│───┐ ┌─│███│───┐
┌────(red││███││ ││ │ └───┘ │ │ └───┘ │
│ `─‘│└───┘│ ├┘ │ │ │ │
│ │ │ │ ▼ ▼ ▼ ▼
▼ ▼ ▼ ▼ ┌───┐ ┌───┐ ┌───┐ ┌───┐
┌───┐ ┌───┐ ┌───┐ ┌───┐ │███│ │███│ │???│ │███│ nodeR/X
│███│ │███│ │???│ │███│nodeR ├───┤ ├───┤ ├───┤ ├───┤
├───┤ ├───┤ ├───┤ ├───┤ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ └───┘ └───┘ └───┘ └───┘
└───┘ └───┘ └───┘ └───┘
BB-2R
情形2
被删除节点的父亲是红色,兄弟节点和侄子全部都是黑色。{:.warning}
- 此时按照B树的观点来看,兄弟节点很瘦,不足以借出关键码,因此需要合并。而又因为P节点是红色,所以从上面节点下来
也不会有影响,所以直接调整完毕 - 按照RB树的观点来看。对于含有R节点的这条通路,少了一个黑色的节点X,多了个黑色节点P,因此第4条性质保持不变。
对于含有S节点的通路来说,互换了通路上的一个红色和黑色节点。所以不会发生任何变化。
nodeP nodeP
.─. ┌───┐
┌ ─ ─ ─ ─ ─(red)─ ─ ─ ┌ ─ ─ ─ ─ ─│███│─────┐
`─‘ │ └───┘ │
▼ ▼ ▼ ▼
nodeS┌───┐ nodeX┌───┐ nodeS .─. nodeR/X┌───┐
┌────│███│────┐ │███│ ┌──── (red)───┐ │███│
│ └───┘ │ └─┬─┘ │ `─‘ │ ├───┤
▼ ▼ ▼ ───────────? ▼ ▼ │***│
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │***│
│███│ │███│ nodeR│███│ │███│ │███│ │***│
├───┤ ├───┤ ├───┤ ├───┤ ├───┤ └───┘
│***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│
│***│ ║ │***│ │***│ │***│ │***│
└───┘ ║ └───┘ └───┘ └───┘ └───┘
║ ┌───────────────────┐
▼ │ directRB change │ ▲
└───────────────────┘ ║
║
nodeP ║
.─.
┌ ─(red)─ ─ ┐ nodeS nodeP
`─‘ .─. ┌───┐┌┐ nodeX
nodeS ▼ ▼nodeX ┌───(red)│███│││──┐
┌───┐ ┌┐ ┌─────────────────────┐ │ `─‘ └───┘└┘ │
┌───│███│──┐ ││ │ indirectBT change │ │ │ │
│ └───┘ │ ├┘ └─────────────────────┘ │ │ │
▼ ▼ ▼ ══════════════════? ▼ ▼ ▼
┌───┐ ┌───┐ ┌───┐ ┌───────────┐ ┌───┐ ┌───┐ ┌───┐
│███│ │███│ │███│nodeR │ merge │ │███│ │███│ │███│nodeR
├───┤ ├───┤ ├───┤ └───────────┘ ├───┤ ├───┤ ├───┤
│***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘
BB-2B
情形3
当被删除节点的父亲为黑色时,且兄弟节点,侄子节点均为黑色,此时{:.warning}
- 按照B树的观点来看,依然需要合并,但是这次将上一节点的唯一节点P拉了下来,因此将导致上层节点发生下溢。
- 按照RB树的观点来看,无论是R通路还是S通路均少了一个黑色节点,因此需要继续向上调整。保证第4条性质不变。
nodeP nodeP
┌───┐ ┌───┐
┌─────────┤███├──────┐ ┌ ─ ─ ─ ─ ─│███│─────┐
│ └───┘ │ └───┘ │
▼ ▼ ▼ ▼
nodeS┌───┐ nodeX┌───┐ nodeS .─. nodeR/X┌───┐
┌────│███│────┐ │███│ ┌──── (red)───┐ │███│
│ └───┘ │ └─┬─┘ │ `─‘ │ ├───┤
▼ ▼ ▼ ───────────? ▼ ▼ │***│
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │***│
│███│ │███│ nodeR│███│ │███│ │███│ │***│
├───┤ ├───┤ ├───┤ ├───┤ ├───┤ └───┘
│***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│
│***│ ║ │***│ │***│ │***│ │***│
└───┘ ║ └───┘ └───┘ └───┘ └───┘ ▲
║ ┌───────────────────┐ ║
▼ │ directRB change │ ║
nodeP └───────────────────┘ ║
┌───┐
┌───│███│───┐ nodeS nodeP
│ └───┘ │ .─. ┌───┐┌┐ nodeX
nodeS ▼ ▼nodeX ┌───(red)│███│││──┐
┌───┐ ┌┐ ┌─────────────────────┐ │ `─‘ └───┘└┘ │
┌───│███│──┐ ││ │ indirectBT change │ │ │ │
│ └───┘ │ ├┘ └─────────────────────┘ │ │ │
▼ ▼ ▼ ══════════════════? ▼ ▼ ▼
┌───┐ ┌───┐ ┌───┐ ┌───────────┐ ┌───┐ ┌───┐ ┌───┐
│███│ │███│ │███│nodeR │ merge │ │███│ │███│ │███│nodeR
├───┤ ├───┤ ├───┤ └───────────┘ ├───┤ ├───┤ ├───┤
│***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│
│***│ │***│ │***│ │***│ │***│ │***│
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘
BB-3
情形4:
被删除节点的父亲为黑色,兄弟节点为红色{:.warning}
这是唯一一个有点,怎么说,不直接的情形
- 按照B树的观点来看,并没有进行下溢操作,仅仅是简单的互换了Super节点的颜色。
- 按照RB树的观点来看,将未知问题转化成为了我们之前遇到过的已知问题。此时被删除节点的父亲为红色,其
兄弟节点为黑色,如果这个兄弟节点有红色儿子,将进入BB-1情形,如果没有,则进入BB-2R情形。幸运的是,
无论哪种情况,都比较简单。
nodeP nodeS
┌───┐ ┌───┐
┌─────────┤███├──────┐ ┌──── │███│─────────┐
│ └───┘ │ │ └───┘ │
▼ ▼ ▼ ▼
nodeS .─. nodeX┌───┐ ┌───┐ .─.nodeP
┌ ─ ─(red)─ ─ ┐ │███│ │███│ ┌────(red)────┐
`─‘ └─┬─┘ ├───┤ │ `─‘ │
▼ ▼ ▼ ───────────? │***│ ▼ ▼
┌───┐ ┌───┐ ┌───┐ │***│ ┌───┐ ┌───┐
│███│ │███│ nodeR│███│ │***│ │███│ nodeX│███│
├───┤ ├───┤ ├───┤ └───┘ ├───┤ └─┬─┘
│***│ │***│ │***│ │***│ ▼
│***│ │***│ │***│ │***│ ┌───┐
│***│ │***│ │***│ │***│ nodeR│███│
└───┘ ║ └───┘ └───┘ └───┘ ├───┤
║ ┌───────────────────┐ │***│
║ │ directRB change │ ▲ │***│
▼ └───────────────────┘ ║ │***│
║ └───┘
nodeS nodeP nodeS nodeP ║
.─. ┌───┐ ┌───┐ .─.
┌───(red)││███│────┐ ┌───│███││(red)────┐
│ `─‘ │└───┘ │ ┌─────────────────────┐ │ └───┘│ `─‘ │
▼ ▼ ▼ │ indirectBT change │ ▼ ▼ ▼
┌───┐ ┌───┐ ┌┐ └─────────────────────┘ ┌───┐ ┌───┐ ┌┐
│███│ │███│ nodeX││─┐ ══════════════════? │███│ │███│ nodeX││─┐
├───┤ ├───┤ └┘ │ ┌───────────┐ ├───┤ ├───┤ └┘ │
│***│ │***│ ▼ │ merge │ │***│ │***│ ▼
│***│ │***│ ┌───┐ └───────────┘ │***│ │***│ ┌───┐
│***│ │***│ nodeR│███│ │***│ │***│ nodeR│███│
└───┘ └───┘ ├───┤ └───┘ └───┘ ├───┤
│***│ │***│
│***│ │***│
│***│ │***│
└───┘ └───┘
结论
上面无论哪种情形,被删除节点的拓扑变换都不会超过O(1)的时间复杂度。
平凡情形:
- 被删除节点x和其后继r不是DoubleBlack,只要将r染成黑色添补x的空位即可。
BB-1 : 被删除节点的父亲节点颜色随意。兄弟节点为黑色,有不少于一个红色侄子节点
- 重染色+旋转完成
- B树意义上的旋转
BB-2R : 被删除节点的父亲节点为红色,兄弟节点,侄子节点皆为黑色
- 重染色
- B树意义上的合并
BB-2B : 被删除节点的父亲节点为黑色,兄弟节点,侄子节点皆为黑色
- 重染色
- B树意义上的合并,DoubleBlack冲突会向上传递
BB-3 : 被删除节点的父亲为黑色,兄弟节点为红色,侄子节点自然为黑色
- 重染色
- B树意义上的无任何变换
- 情形转化为BB-1或者BB-2R
红黑树总结
学习红黑树的插入和删除,主要是明白为什么其只需要常数次拓扑变换就可以调整回来,即其到底比AVL树优秀在哪里。
并不是说去背诵它到底怎么插入,怎么删除。不难发现凡是可能造成连锁反应的操作,只会涉及染色这种操作。而
一旦涉及拓扑调整,最多俩次就调整完毕。
以上是关于邓俊辉数据结构学习-8-3-红黑树的主要内容,如果未能解决你的问题,请参考以下文章