红黑树插入 = 二叉搜索树插入 + 插入后修复(保持5大性质)
插入过程步骤:
10(B)
/
5(R)
10(B)
/
5(R)
/
1(R)
违背性质:5 连续红色节点出现了
场景 | 条件 | 修复操作 |
---|---|---|
情况 1:叔红 | 父红 + 叔红 | 父、叔变黑,祖父变红,递归上移 |
情况 2:叔黑,当前是“内拐” | 父红 + 当前是左-右或右-左 | 将其变为“外拐”,旋转父节点 |
情况 3:叔黑,当前是“外拐” | 父红 + 当前是左-左或右-右 | 父变黑,祖父变红,旋转祖父节点 |
G(B) G(R)
/ \ => / \
P(R) U(R) P(B) U(B)
/
N(R)
➡️ 颜色翻转,向上继续修复
G(B) G(B) G(B)
/ / /
P(R) N(R) N(R)
\ => / => /
N(R) P(R) P(B)
/
NULL
➡️ 先旋转父节点,把内拐变外拐,再进入情况 3
G(B) P(B)
/ => / \
P(R) N(R) G(R)
/
N(R)
➡️ 单旋 + 着色即可修复
红黑树删除更复杂,因为:
按 BST 方式删除节点(含替换节点);
如果删除的是红色节点:无需修复;
如果删除的是黑色节点:
场景 | 条件 | 修复方法 |
---|---|---|
情况 1:兄弟红 | 父黑 + 兄弟红 | 旋转兄弟上移(变黑),转化为其他情况 |
情况 2:兄弟黑且兄弟子黑 | 兄弟为黑,兄弟左右子都黑 | 兄弟变红,额外黑传给父节点 |
情况 3:兄弟黑 + 兄弟“内侧”子红 | 转为情况4前的预处理 | 旋转兄弟,变成“外侧”红子 |
情况 4:兄弟黑 + 兄弟“外侧”子红 | 父子重新染色 + 单旋转修复 |
P(B) S(B)
/ \ => / \
N S(R) P(R) SR
/ \ / \
SL SR N SL
➡️ S 旋转上来,把红兄弟转为黑兄弟(继续向下修复)
P(B) P(B)
/ \ => / \
N S(B) N S(R)
/ \
BL BR
➡️ S 染红,P 继续下沉额外黑
对象 | 插入 | 删除 |
---|---|---|
默认颜色 | 新节点红 | 删除后黑缺失(额外黑) |
主要破坏 | 连续红 | 黑高失衡 |
修复方式 | 父变黑 / 祖父旋转 | 兄弟染色 / 多重旋转 |
旋转位置 | 祖父 | 父或兄弟 |
是否递归 | 可能 | 可能 |