(转载)数据结构与算法整理总结---红黑树


原文作者:oliver-l
转自链接:https://learnku.com/articles/43763

目录

什么是 “平衡⼆叉查找树”?

如何定义⼀棵 “红⿊树”?

为什么说红⿊树是 “近似平衡” 的?

实现红⿊树的基本思想

插⼊操作的平衡调整

删除操作的平衡调整

1. 针对删除节点初步调整

2. 针对关注节点进⾏⼆次调整


什么是 “平衡⼆叉查找树”?



平衡⼆叉树的严格定义是这样的:⼆叉树中任意⼀个节点的左右⼦树的⾼度相差不能⼤于 1。从这个定义来看,完全⼆叉树、满⼆叉树其实都是平衡⼆叉树,但是⾮完全⼆叉树也有可能是平衡⼆叉树。

平衡⼆叉查找树不仅满⾜上⾯平衡⼆叉树的定义,还满⾜⼆叉查找树的特点。最先被发明的平衡⼆叉查找树是 AVL 树,它严格符合我刚讲到的平衡⼆叉查找树的定义,即任何节点的左右⼦树⾼度相差不超过 1,是⼀种⾼度平衡的⼆叉查找树。

但是很多平衡⼆叉查找树其实并没有严格符合上⾯的定义(树中任意⼀个节点的左右⼦树的⾼度相差不能⼤于 1),⽐如红⿊树,它从根节点到各个叶⼦节点的最⻓路径,有可能会⽐最短路径⼤⼀倍。

平衡⼆叉查找树中 “平衡” 的意思,其实就是让整棵树左右看起来⽐较 “对称”、⽐较 “平衡”,不要出现左⼦树很⾼、右⼦树很矮的情况。这样就能让整棵树的⾼度相对来说低⼀些,相应的插⼊、删除、查找等操作的效率⾼⼀些。

如何定义⼀棵 “红⿊树”?



平衡⼆叉查找树其实有很多,⽐如,Splay Tree(伸展树)、Treap(树堆)等,但是我们提到平衡⼆叉查找树,听到的基本都是红⿊树。它的出镜率甚⾄要⾼于 “平衡⼆叉查找树” 这⼏个字,有时候,我们甚⾄默认平衡⼆叉查找树就是红⿊树,那我们现在就来看看这个 “明星树”。

顾名思义,红⿊树中的节点,⼀类被标记为⿊⾊,⼀类被标记为红⾊。除此之外,⼀棵红⿊树还需要满⾜这样⼏个要求:

  1. 根节点是⿊⾊的;
  2. 每个叶⼦节点都是⿊⾊的空节点(NIL),也就是说,叶⼦节点不存储数据;
  3. 任何相邻的节点都不能同时为红⾊,也就是说,红⾊节点是被⿊⾊节点隔开的;
  4. 每个节点,从该节点到达其可达叶⼦节点的所有路径,都包含相同数⽬的⿊⾊节点;

为什么说红⿊树是 “近似平衡” 的?



平衡⼆叉查找树的初衷,是为了解决⼆叉查找树因为动态更新导致的性能退化问题。所以,“平衡” 的意思可以等价为性能不退化。“近似平衡” 就等价为性能不会退化的太严重。

⼆叉查找树很多操作的性能都跟树的⾼度成正⽐。⼀棵极其平衡的⼆叉树(满⼆叉树或完全⼆叉树)的⾼度⼤约是 log2n,所以如果要证明红⿊树是近似平衡的,我们只需要分析,红⿊树的⾼度是否⽐较稳定地趋近 log2n 就好了。

⾸先,我们来看,如果我们将红⾊节点从红⿊树中去掉,那单纯包含⿊⾊节点的红⿊树的⾼度是多少呢?

红⾊节点删除之后,有些节点就没有⽗节点了,它们会直接拿这些节点的祖⽗节点(⽗节点的⽗节点)作为⽗节点。所以,之前的⼆叉树就变成了四叉树。

前⾯红⿊树的定义⾥有这么⼀条:从任意节点到可达的叶⼦节点的每个路径包含相同数⽬的⿊⾊节点。我们从四叉树中取出某些节点,放到叶节点位置,四叉树就变成了完全⼆叉树。所以,仅包含⿊⾊节点的四叉树的⾼度,⽐包含相同节点个数的完全⼆叉树的⾼度还要⼩。

完全⼆叉树的⾼度近似 log2n,这⾥的四叉 “⿊树” 的⾼度要低于完全⼆叉树,所以去掉红⾊节点的 “⿊树” 的⾼度也不会超过 log2n。

我们现在知道只包含⿊⾊节点的 “⿊树” 的⾼度,那我们现在把红⾊节点加回去,⾼度会变成多少呢?

从上⾯我画的红⿊树的例⼦和定义看,在红⿊树中,红⾊节点不能相邻,也就是说,有⼀个红⾊节点就要⾄少有⼀个⿊⾊节点,将它跟其他红⾊节点隔开。红⿊树中包含最多⿊⾊节点的路径不会超过 log2n,所以加⼊红⾊节点之后,最⻓路径不会超过 2log2n,也就是说,红⿊树的⾼度近似 2log2n。

所以,红⿊树的⾼度只⽐⾼度平衡的 AVL 树的⾼度(log2n)仅仅⼤了⼀倍,在性能上,下降得并不多。这样推导出来的结果不够精确,实际上红⿊树的性能更好。

实现红⿊树的基本思想



不知道你有没有玩过魔⽅?其实魔⽅的复原解法是有固定算法的:遇到哪⼏⾯是什么样⼦,对应就怎么转⼏下。你只要跟着这个复原步骤,就肯定能将魔⽅复原。

实际上,红⿊树的平衡过程跟魔⽅复原⾮常神似,⼤致过程就是:遇到什么样的节点排布,我们就对应怎么去调整。只要按照这些固定的调整规则来操作,就能将⼀个⾮平衡的红⿊树调整成平衡的。

前面定义了红黑树满足的四点要求,在插⼊、删除节点的过程中,第三、第四点要求可能会被破坏,⽽我们今天要讲的 “平衡调整”,实际上就是要把被破坏的第三、第四点恢复过来。

在正式开始之前,我先介绍两个⾮常重要的操作,左旋(rotate left)、右旋(rotate right)。左旋全称其实是叫围绕某个节点的左旋,那右旋的全称估计你已经猜到了,就叫围绕某个节点的右旋。

自己思考:左旋右旋有啥意义呢?交换颜色,变换位置(eg: 右旋中 x.right 原本在 右边,后来变到左边)

左旋:

右旋:

【插⼊】操作的平衡调整


红黑树插入的4种情形

(1)新节点位于根节点,其没有父节点时, 处理思路:将该插入的红色节点直接设为黑色即可;   -------处理简单

(2)新节点的父节点已然是黑色时,            处理思路:因为插入的节点是红色,而父节点是黑色,所以不用动,这已然是一颗红黑树 ;------处理简单

(3)父节点和叔节点都是红色时,                处理思路:a.将父节点和叔节点设为黑色;  b.将祖父节点设为红色;   c.将祖父节点设为当前节点,并继续对新当前节点进行操作

(4)父节点是红色,叔节点是黑色时,又分如下四种情况:

  • 当前节点是父亲的左孩子,父亲是祖父的左孩子(Left-Left),      处理思路:a.将祖父节点右旋;b.交换父节点和祖父节点的颜色
  • 当前节点是父亲的右孩子,父亲是祖父的左孩子(Right-Left),    处理思路:a.将父节点左旋,并将父节点作为当前节点; b.然后再使用Left Left情形
  • 当前节点是父亲的右孩子,父亲是祖父的右孩子(Right-Right),  处理思路:a.将祖父节点左旋;b.交换父节点和祖父节点的颜色
  • 当前节点是父亲的左孩子,父亲是祖父的右孩子(Left-Right),    处理思路:a.将父节点右旋,并将父节点作为当前节点; b.然后再使用Right Right情形
  •                                       

插入规则

红⿊树规定,插⼊的节点必须是红⾊的

红⿊树的平衡调整过程是⼀个【迭代】的过程

我们把正在处理的节点叫作 【关注节点/当前节点】 。【关注节点/当前节点】会随着不停地迭代处理,⽽不断发⽣变化。最开始的关注节点就是新插⼊的节点。

【删除】操作的平衡调整


红⿊树插⼊操作的平衡调整还不是很难,但是它的删除操作的平衡调整相对就要难多了。不过原理都是类似的,我们依旧只需要根据关注节点与周围节点的排布特点,按照⼀定的规则去调整就⾏了。

一、从树中删除节点X(以寻找后继节点的方式进行删除

情况①:如果X没有孩子,且如果X是红色,直接删除X;如果X是黑色,则X为当前节点进行旋转调色,最后删掉X

情况②:如果X只有一个孩子C,交换X和C的数值,再对新X进行删除。根据红黑树特性,此时X不可能为红色,因为红色节点要么没有孩子,要么有两个黑孩子。此时以新X当前节点进行情况①的判断

情况③:如果X有两个孩子,则从后继中找到最小节点D,交换X和D的数值,再对新X进行删除。此时以新X为当前节点进行情况①或②的判断

二、旋转调色(N=旋转调色的当前节点[等于情况①中的X]P=N的父亲,W=N的兄弟,Nf=N的远侄子,Nn=N的近侄子

情况1:N是根或者N是红色,则:直接将N设为黑色

情况2:N不是根且N是黑色,且W为红色,则:将W设为黑色,P设为红色,对P进行旋转(N为P的左子时进行左旋,N为P的右子时进行右旋),将情况转化为情况1、2、3、4、5

情况3:N不是根且N是黑色,且W为黑色,且W的左右子均为黑色,则:将W设为红色,将P设为当前节点进行旋转调色,将情况转化为情况1、2、3、4、5

情况4:N不是根且N是黑色,且W为黑色,且Nf为黑色,Nn为红色,则:交换W与Nn的颜色,并对W进行旋转(N为P的左子进行右旋,N为P的右子进行左旋),旋转后N的新兄弟W有一个红色WR,则转换为情况5

情况5:N不是根且N是黑色,且W为黑色,且Nf为红色,Nn为黑色,则:将W设为P的颜色,P和Nf设为黑色,并对P进行旋转(N为P的左子进行左旋,N为P的右子进行右旋),N设为根

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值