红黑树,它只是一棵规则多的平衡树

红黑树

20201214

22:19

 

概述

红黑树是一种平衡二叉树,它的构建必须遵守红黑树的原则,由此来保证平衡性(事实上是黑色节点平衡)。红黑树的核心操作是旋转和染色,通过二者来自平衡。所以本质上它就是一种非常类似AVL树的二叉搜索树,类似的结构有B-Tree,B+Tree,都是遵守规则加上旋转达到自平衡。

插入和删除其实本质上类似,都是改变-自平衡,但是删除的规则列表极多。红黑树的实现困难来源于需要考虑的case太多,但并不复杂。

以下是红黑树的核心:

  • 空节点视为黑色,可以保持整个算法的一致性
  • 染色的核心是:不改变左右子树的黑节点数量(性质5),由此发展出一系列case下的规则,但核心不变。
  • 旋转的核心是:旋转可以改变左右子树的黑节点数量(在其他平衡树中,可能是高度),再加上染色规则即可以完成红黑树的自平衡过程。

平衡树的核心:

  • 旋转的基本核心,z形和直线形,平衡树常规操作
  • 删除的基本核心,找到后继(中序第一个,或者右子树最左的一个),和删除节点交换,然后删除后继位置,平衡树常规操作,该操作主要是先保证树的大小正确性,即左子树<root<右子树

原则

  • 性质1:每个节点要么是黑色,要么是红色。
  • 性质2:根节点是黑色。
  • 性质3:每个叶子节点(NIL)是黑色。
  • 性质4:每个红色结点的两个子结点一定都是黑色。
  • 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

其实真正有内容的性质是:

  • 性质4:每个红色结点的两个子结点一定都是黑色。
  • 性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

性质4看起来简单,实际上蕴含很多信息,一种比较好的表述是,红色节点的父子节点必定是黑色节点。性质5很大程度上决定的平衡树的平衡性。

插入

默认插入红色节点,这是因为插入红色节点改变的性质少,好调整,只可能改变了性质4。

插入的规则不多,非常好理解。简单的情况参考 <https://www.jianshu.com/p/e136ec79235c>

 

这里以复杂情况为例:

case 1: 插入I,其叔父节点(s)为红,则为了不改变左右子树,染色规则如下图。这个时候子树已经符合性质,剩下pp节点,将其单做插入节点,递归处理即可(当然,考虑所有插入情况)

case 2: 插入I,其叔父是黑色(空节点视为黑色)

注意到和AVL树一样,旋转同样有Z形和直线形,首先把Z转为直线形,然后就进入该case,该case的处理方案非常简单,不改变左右子树黑色节点数的情况下,染色,旋转。

删除

删除操作的核心是

  • 平衡树的删除的基本规则,找到后继替换,删除后继位置
  • 如何自平衡?答:染色,旋转,自平衡
  • 什么时候旋转,答:左右子树黑节点不等的时候
  • 如何染色,答:规则列表。

所以上面的都好理解,剩下的染色问题只不过就是规则而已。

以下以一个为例,可视化可以参考 https://www.youtube.com/watch?v=eO3GzpCCUSg ,该视频列出了10种删除情况,删除后需要时时考虑,黑色节点失衡吗?需要旋转吗?至于染色,那是规则列表了。

删除8,需要找到后继节点,即11。那么先拿出11,相当于删除11,找到11的后继(黑色,空节点),拿出11,替换8,删除原来位置。

此时8子树左右子树黑色节点失衡(黑高度失衡,注意空节点也算,只是它本身不算入黑高度,比如8的左节点黑高度为2,右子节点黑高度为1)。

所以,显然到了旋转的时机了。注意到,这是z形,需要先转为直线。这和插入遇到的case是一样的。

忽略染色(因为都是规则,核心是不改变左右子树黑节点数),然后旋转

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值