初识红黑树

这篇文章是直接从我的笔记里复制出来的,关于格式我没有去整理,若影响阅读体验,请见谅。
关于红黑树的知识点,我没有仔细去参考网上的那些千篇一律的复制文章,很多部分都是用自己认为的的想法来讲述的,可能会有理解错误,欢迎大家指正。后续部分(删除还有代码实现)我等有时间再完成。

红黑树是一种节点有颜色标记的(非严格)平衡二叉查找树,符合以下特性
1.节点是红色或者黑色
2.根节点是黑色
3.所有的叶子节点是黑色
4.每个红色节点都必须有两个黑色子节点
5.任一结点到其每个叶子节点的所有简单路径都包含相同数目的黑色节点
在这里插入图片描述
这个图就是一个典型的红黑树,这里需要注意的就是第5点特性,任一节点到其根节点路径上的黑色节点数目相同。依据这点,红黑树不需要严格意义上的平衡,它有一套自己平衡的定义——黑高度相同,这就造成存在最坏情况(一路的红黑相间实际高度接近另一路全黑的2倍)。
————以前理解偏了,把红黑树当成avl,踩了很多坑,这里实名diss算法导论的中文翻译和某些CSDN的复制。

在理解红黑树之前可以先了解一下2-3-4树,2-3-4树是一个四阶的B树(平衡多叉查找树),节点分为三种:
2- 节点:包含1个元素、有2个子节点
3- 节点:包含2个元素,有3个子节点
4- 节点:包含3个元素,有4个子节点
2-3-4树的插入过程:
向最下一层插入
元素插入到合适的结点中,将该节点升元(2-节点变为3-节点,3-节点变为4-节点)
4-节点的升元是先将中间元素提到父节点,将父节点升元,原4-节点变为两个2-节点再对2-节点执行升元,若父节点也是4-则递归,到根节点后树高度+1。

红黑树的插入:
新插入结点应为红色,所有路径上的黑色结点数量不会发生变化
对最下层黑色结点(没有有效子节点)插入,直接替换Nil节点,等效于2-结点升元。
对最下层黑色结点(一个有效节点,该有效节点必定为红色)插入,视情况(大小)插入旋转变色。等效3-结点升元。
由以上升元得来的结构,黑色结点应该有两个红色子节点,再对这个结构升元(插入),要将黑色父节点染色为红色,两个红色子节点染为黑色,再执行插入。等效4-节点升元(递归情况有所不同,红黑树的判断更为复杂)。
———这里将要插入的红色结点与插入后的父节点看作是一个2-3-4树的多元素节点,方便理解过程。

插入一个知识点,红黑树的旋转。选择分为左旋和右旋。对一个节点做左旋,即是将该节点变成该节点右孩子的做孩子,原右孩子取代该节点的位置。右旋反之。
在这里插入图片描述

插入总结:
插入节点须为红色,才不会影响该路径的黑高度,但是如果插入点的父节点为红色,就破坏了红黑树的第4特性,因此需要变色。
父节点染黑就会使得该路径的黑节点数增加,破坏特性5,要维持红黑树特性,则需将其他路径的黑节点数增加或者在往上一层的黑节点减少。
如果将祖父节点染红,则叔叔节点一脉的黑高度都少了1,所以这里要做一步判断。叔叔节点如果是红色,祖父节点染红后之间将叔叔节点染黑就可以了,(叔叔节点是黑色时,需要将祖父节点旋转下来,父节点占据祖父节点位置,新生节点染黑)
祖父节点位置染红后如果祖父节点的父节点是红色,就会重复出现上面连续红色的情况,这里做递归就可以。
这里基本涵盖了所有的插入情况,其实插入只用分为两种情况,一种是插入后不破坏红黑树结构,一种是破坏了红黑树结构。破坏结构了就需要做旋转和染色,对节点旋转只分为两种情况(左旋和右旋),旋转时需要注意每个节点的子节点是否为NULL,不要对NULL节点的内容操作。染色有它自己的平衡原则,要么所有节点都增加或减少黑色节点,要么变色路径上有加就有减(增加一个黑色节点,就必须减少一个黑色节点)。

平衡树的删除情况就远比插入复杂,插入只考虑往最下层插入红色,而删除可能出现在任意节点、任意颜色。要考虑的情况要多了很多。但是简化思路来看,也是两种情况,删除后破坏或者没破坏红黑树的结构。破坏结构后也是需要旋转染色来调整,删除了黑色节点后要做的就是将其他所有路径的黑色节点-1,或者使当前路径的黑色节点+1;删除红色节点时,一般考虑红色节点的两个子节点放置就可以了。还是可以类比B树的删除。
2-3-4树的删除:
查找最近叶子节点中的元素替代被删除元素
降元
2-节点中只有一个元素,删除后用兄弟节点元素补充,兄弟元素中没有可以借用来补充的时候,将父节点降元,递归至根节点时高度-1

20240407时隔多年做复健来手写这部分代码的时候才发现,之前的想的太简单了,有部分思路走偏了。
现在对插入做了基本的实现https://note.youdao.com/s/Tp8nKKQx,等删除部分完善后再整理格式吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值