基础
既然AVL已经很好了,为什么还要红黑树?
AVL树虽然查找效率更高(更平衡),但插入和删除时需要频繁旋转,维护成本较高;红黑树通过“弱平衡”减少旋转次数,使得插入和删除更高效,更适合工程实现。
| 结构 | 平衡程度 | 查询 | 插入/删除 |
|---|---|---|---|
| AVL | 严格平衡 | 更快 | 更慢(旋转多) |
| 红黑树 | 弱平衡 | 稍慢 | 更快(旋转少) |
红黑树的核心思想:不追求高度差<=1,而是用“颜色规则”来控制树的平衡。
五大性质(颜色规则)
- 每个节点是红色或黑色
- 根节点是黑色
- 叶子节点(nullptr)是黑色
- 红节点不能相邻
- 黑高一致(从任意节点到所有叶子路径,黑色节点数量必须相同)
本质:保证“最长路径<=最短路径的2倍”
红黑树调整的核心问题:
首先,插入新节点必须是红色,因为如果插黑会破坏“黑高一致”的规则,插红只可能违反“红节点不能相邻”,所以红黑树调整的核心问题就是消除“红红冲突”。
三种情况
叔叔是红色
G(黑)
/ \
P(红) U(红)
/
N(红)--红红冲突
子和父都是红-》冲突-》父变黑-》父这一侧多了一个黑-》叔变黑-》 祖父这一侧多了层黑-》需要祖父变红来减少一个黑,但可能导致祖父和祖父的父亲红红冲突,所以继续向上调整(递归/循环)。
- 父变黑
- 叔变黑
- 祖父变红
- 向上继续处理
G(红)--可能导致新的红红冲突
/ \
P(黑) U(黑)
/
N(红)
叔叔是黑色+直线(LL/RR)
旋转+变色
LL:
G(黑)
/ \
P(红) nullptr(黑)
/
N(红) --红红冲突
右旋:
P(红)
/ \
N(红) G(黑)
变色:
P(黑)
/ \
N(红) G(红)
RR:
G(黑)
/ \
nullptr(黑 ) P(红)
\
N(红)
左旋:
P(红)
/ \
G(黑) N(红)
变色:
P(黑)
/ \
G(红) N(红)
故通过一次旋转(LL对应右旋,RR对应左旋)并调整颜色(父变黑,祖变红)即可。
叔叔是黑色+折线(LR/RL)
先旋转变成直线,然后就变成了情况二。
G(黑)
/
P(红)
\
N(红)