数据结构 - 学习笔记 - 红黑树前传——234树

简介

234树——234Trees
在学习红黑树前需要先了解234树。因为红黑树就是由234树演变出来的。(红黑树是234树的一种实现)
了解了234树才能明白红黑树旋转和颜色变化的底层逻辑。

结点类型

结点元素个数子结点个数
子结点值域
对应红黑树结点
2结点1个元素。
如:a
2个子结点或子结点
( , a), (a, )
黑色a
3结点2个元素。
如:a < b
3个子结点或子结点
( , a) , (a, b) , (b, )
父结点必需是黑色且有2种情况
1. 红色a ←左子— 黑色b
2. 黑色a —右子→ 红色b
4结点3个元素。
如:a < b < c
4个子结点或子结点
( , a) , (a, b) , (b, c) , (c, )
┌──黑色b──┐
红色a                红色c

红黑树对应关系图示

在这里插入图片描述

  1. 上图中没有画出具体的子结点 仅用虚线框标识了一下子结点的取值范围。
  2. 不难看出,只要将红黑树中的红结点向上一提,与父结点合并,就反推出了234树
  3. 同时根据3结点的特性,可以看出234树红黑树一对多的关系。
  4. 在平时分析红黑树时,可以直接在脑海里映射成234树来分析。这样变化旋转操作就有据可依,而不是死记硬背了。

插入

插入规则

插入场景插入前插入示例值插入后结论
当前无结点5[⑤]直接插入就完事了。
当前2结点[5]3[③, ⑤]2结点升级为3结点
当前3结点[3, 5]7[③, ⑤, ⑦]3结点升级为4结点
当前4结点[3, 5, 7]8[⑤]
[③], [⑦, ⑧]
4结点 插入新值时,会触发分裂
1. 中间值 ⑤ 上升,与父结点合并。
2. 找到 ⑧ 的插入位置。
    插入后与⑦合并得到 [⑦, ⑧]。

插入步骤整体演示

先看一下演示,后面还有对 2, 3, 4 结点的分别说明。
下图演示了234树的插入步骤,以及触发分裂的效果。(新插入的元素,按红黑树规则标为红色)
在这里插入图片描述

下图对应234树插入步骤,在右侧列出对应的红黑树。因为3结点红黑树存在两种情况,所以按排列组合方式一一列出。
对照前文的与红黑树对应关系,可以看到黑红颜色背后的逻辑来源于234树
在这里插入图片描述

2, 3, 4 结点分别说明

1. 在2结点插入

2结点插入新值,直接升级为3结点,无需任何调整。
在这里插入图片描述

2. 在3结点插入(红黑树旋转+变色)

3结点插入新值,直接升级为4结点,无需任何调整。
但在3结点对应的红黑树中,可能出现不平衡的情况。需要旋转调整实现平衡。
在这里插入图片描述

  1. 旋转方向的逻辑可以想象天平。左边重了往右挪(旋)右边重了往左挪(旋)
  2. 从上图可以看到有3个位置能插入子结点。对应 6 种红黑树的情形。
  3. 其中有2种是平衡的,无需调整。剩下4种 需要通过旋转+变色实现平衡。

3. 在4结点插入(红黑树变色)

3.1. 从234树→红黑树

先简单的把 4结点红黑树 对应关系,罗列出来。根据新结点插入的位置不同,对应的红黑树也有所差异:
在这里插入图片描述

对应上图的步骤序号。

  1. 原234树为 ③⑤⑦
  2. 插入新元素。将要触发分裂。
  3. 先分裂。然后按新值大小,找到插入位置,与原有的2结点 合并成为3结点
    3.1. 中值上提为父结点,如果原本有父结点,分裂出去的结点,与原父结点合并。
    3.2. 如果原来的父结点也是一个4结点,将递归触发分裂
    3.3. 剩下两个结点,小的为左,大的为右。
  4. 234树结点转红黑树结点。
    4.1. 所有 2结点 变为黑色。
    4.2. 3结点 展开,上黑下红。

3.2. 触发分裂

单独分析一下触发分裂效果。
在这里插入图片描述

  1. 从左向右:演示了从234树的角度来染色的逻辑。
  2. 从右向左:演示了从红黑树的角度来染色的公式
  3. 如果当前操作的只是一颗子树。比如祖父结点也是红色,则出出了②⑤两个连续的红结点,需要递归处理,直至根。
3.3. 对应红黑树有4种情形需要变色实现平衡

在这里插入图片描述

  1. 【234树】 插入新元素。将要触发分裂。
  2. 【234树】 先分裂。然后找到待插入的目标位置,与原有的2结点 合并成为3结点
  3. 【红黑树】 这是一个过度状态,为了便于观察才把它画出来。(3结点展开,但未调色,暂时还保持着不平衡的状态,便于观察)
  4. 【红黑树】 叔伯结点变黑祖父结点变红
    4.1. 结点与祖父结点调换颜色:满足红结点子必的定义。同时对于插入新结点的这一路径来说黑结点数未发生变化。
    4.2. 叔伯结点变成黑色祖父结点原本作为公共的黑结点,挪给左路后,右路就少了一个黑结点。因此 叔伯要站出来变维持平衡。
  5. 【红黑树】 最后祖父结点更新为当前结点。
    5.1. 判断曾祖是否为红色。如果是,则需要向上递归调整颜色,一直到根。
    5.2. 如果是根,直接染

删除

删除操作:根据删除目标所在位置不同,共有几种情况需要分别处理。

删除规则

1. 删除目标子结点

  1. 找到目标前驱后继结点。
  2. 目标前驱后继交换。
  3. 交换后目标转变成了无子结点,按无子结点删除规则处理。

2. 删除目标子结点

  1. 目标在4结点中,删除后变成3结点。
  2. 目标在3结点中,删除后变成3结点。
  3. 目标是2结点,有三种情况:
    3.1. 兄弟是3结点4结点
    3.2. 两个兄弟结点都是2结点,但父结点3结点4结点
    3.3. 兄弟结点都是2结点

2, 3, 4 结点分别说明

1. 在4结点删除

删除一个元素,变成3结点。保持平衡。
4结点 的删除,如果忽略掉它的兄弟结点。本质上还是一个3结点的删除。
对应红黑树:

  • 红结点:直接删除即可。
  • 黑结点:删除黑结点,红结点补位,并变成黑色。

在这里插入图片描述

  1. 234树结点,蓝色 标出是要删除的目标。
  2. 转为对应的红黑树
  3. 删除目标结点。
  4. 如果删的是父结点子结点上移补位。
  5. 补上来的结点染成原父结点的颜色。如果是根结点 直接填充黑色。(虽然单看234树转过来的这个局部,父结点必定是黑色。但在一个完整红黑中,父结点有可能是红色)

2. 在3结点删除

删除一个元素,变成2结点。保持平衡。

  • 红结点:直接删除即可。
  • 黑结点:删除黑结点,红结点补位,并变成黑色。

在这里插入图片描述

  1. 原234树结点,蓝色 标出是要删除的目标。
  2. 转为对应的红黑树
  3. 删除目标结点。
  4. 如果删的是父结点子结点上移补位。
  5. 补上来的结点染成原父结点的颜色。如果是根结点 直接填充黑色

3. 在2结点删除

删除结点后,当前位置空出,红黑树失去平衡。需要向父兄结点借元素借兵补充。

3.1. 兄弟是3或4结点
  1. 通过从兄弟节点借调元素,将2节点转变为3节点。(通过左旋右旋实现转变。)
  2. 然后按2、3节点规则删除目标。

在这里插入图片描述

3.2. 兄弟都是2结点,父是3或4结点
  1. 向父结点借来 ④,合并出新的结点 [③, ④, ⑥]。
  2. 4结点规则删掉目标。

在这里插入图片描述

3.3. 父兄结点都是2结点
  1. 向父借来元素,合并出新的4结点
  2. 4结点规则删掉目标。

在这里插入图片描述

如果当前是子树,则父结点需要递归向上借调。
在这里插入图片描述 在这里插入图片描述

总结

  1. 可以将红黑树看作是234树的一个具体实现。
  2. 一颗234树可以对应多个红黑树。(因为 3结点 对应 红黑树 时可以左倾,也可以右倾)
  3. 明明是包含123个元素的结点,为什么不叫123树而叫234树。我的理解是:因为树的特性就是分叉,结点的命名是按它的分叉能力来的(而不是按结点包含的元素个数)。n结点就是能分n个叉的结点。(吐槽:真是跟制动有异曲同工之妙。但是二叉树,二叉树叫的又那么顺口,好吧,当我没说。)
  4. 234树 就是 4阶B树(four-order balance tree)。也就是允许结点最多有4个子结点平衡多路查找树。
  5. 234树 是倒着长的。新元素插入到叶子,然后触发分裂向上提升元素成为父结点。
    5.1. 如果原本有父结点,则与父结点合并。
    5.2. 如果满足条件还会递归触发分裂,前面 插入-触发分裂 有详细讲。

参考资料

笑虾:数据结构 - 学习笔记 - 红黑树
2-3-4 Trees

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值