C语言编写红黑树

一、平衡条件

  1. 节点非黑既红
  2. 根节点是黑色
  3. 叶子(NIL)结点是黑色
  4. 红色节点下面接两个黑色节点
  5. 从根节点到叶子结点路径上,黑色节点数量相同

注:
1. 第4条和第5条条件,注定了,红黑树中最长路径是最短路径的长度的 2 倍。
2. 本质上,红黑树也是通过树高来控制平衡的。
3. 红黑树比 AVL 树树高控制条件要更松散,红黑树在发生节点插入和删除以后,发生调整的概率,比 AVL 树要更小。

二、理解层面

  1. 理解红黑树的插入调整,要站在祖父节点向下进行调整
  2. 理解红黑树的删除调整,要站在父节点向下进行调整
  3. 插入调整,主要就是为了解决双红情况
  4. 新插入的节点一定是红色,插入黑色节点一定会产生冲突,违反条件5,插入红色
    结点不一定发生冲突;
  5. 把每一种情况,想象成一棵大的红黑树中的局部子树
  6. 局部调整的时候,为了不影响全局,调整前后的路径上黑色节点数量相同

三、插入策略

  1. 叔叔节点为红色的时候,修改三元组小帽子,改成红黑黑
  2. 叔叔节点为黑色的时候,参考 AVL 树的失衡情况,分成 LL,LR,RL,RR , 先参考 AVL 树的旋转调整策略,然后再修改三元组的颜色,有两种调整策略:红色上浮,红色下沉
  3. 两大类情况,包含 8 种小情况

代码实现:
结点定义和叶子结点(NIL)的定义以及结点初始化和析构
在这里插入图片描述
插入操作:插入操作依然是二叉排序树相同操作只是在回溯阶段进行插入调整
4. 插入调整,发正在递归的回溯阶段
5. 插入调整代码中,使用 goto 语句,8行代码,变成了4行
6. 处理根节点一定是黑色,通过代码封装,insert->__insert
在这里插入图片描述
第一种情况:父结点双红需要将两个子结点变黑,祖父结点变红即可

在这里插入图片描述
第二种情况:父结点一黑一红,且红色父结点下出现冲突,需要同AVL树一样操作完后将红色上浮

在这里插入图片描述
在这里插入图片描述
三、删除调整发生的前提

  1. 删除红色节点,不会对红黑树的平衡产生影响
  2. 度为1的黑色节点,唯一子孩子,一定是红色
  3. 删除度为1的黑色节点,不会产生删除调整
  4. 删除度为0的黑色节点,会产生一个双重黑的 NIL 节点
  5. 删除调整,就是为了干掉双重黑
    在这里插入图片描述
    注:删除结点的操作只是在AVL树的删除节点基础上在删除度为0的结点时会出现双重黑的结点,接下来的删除调整是旨在解决出现双重黑的结果。

删除调整

  1. 双重黑节点的兄弟节点是黑色,兄弟节点下面的两个子节点也是黑色,父节点增加一重黑色,双重黑与兄弟节点,分别减少一重黑色。
  2. 兄弟节点是黑色,并且,兄弟节点中有红色子节点
    1. R(兄弟)R(右子节点),左旋,新根改成原根的颜色,将新根的两个子节点,改成黑色
    2. R(兄弟)L(左子节点),先小右旋,对调新根与原根的颜色,转成上一种情况
    3. LL 同理 RR
    4. LR 同理 RL
  3. 兄弟节点是红色,通过旋转,转变成兄弟节点是黑色的情况
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值