数据结构与算法(一)---红黑树

本文介绍了红黑树的基本概念和性质,对比了红黑树与二叉平衡树的区别。详细阐述了红黑树的查找、插入操作,包括插入时的节点上色和旋转处理。此外,还深入探讨了红黑树的删除操作,分析了不同删除情况下的处理策略,如节点无子节点、单子节点和双子节点的情况。最后总结了删除后的平衡调整方法。
摘要由CSDN通过智能技术生成

数据结构与算法(一)—红黑树



二叉排序树的性能

  对于二叉排序数来说,插入节点的顺序决定了二叉排序树的形状,下例表示了两种查找性能完全不同的二叉排序树在这里插入图片描述
  这种树形的二叉查找树称为完全二叉查找树,查找时间复杂度为O(logn);但由于插入顺序的改变,存储而来的二叉查找树型也可能为下图所示结构,这样的树形情况下的二叉查树就丢失了原有的查找效率优势,有时甚至要遍历整个二叉树。
在这里插入图片描述

红黑树简介

一、红黑树的概念

  红黑树是一种具有特殊规则的二叉树查找树,可以在二叉查找树进行插入、删除操作的时候保证树的“平衡性”。

二、红黑树与二叉平衡树

不同点:

  1、红黑树追求的是大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。

  2、平衡二叉树追求绝对平衡,条件比较苛刻(任意左右两个子树的高度差的绝对值不超过1),实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。

相同点:

  进行插入或者删除是都是需要进行一定的平衡操作的。

三、红黑树的性质

· 1.每个节点是红色或者是黑色的;
· 2.根节点是黑色的;
· 3.每个叶子节点是黑色(NIL节点);
· 4.每个红色节点的两个子节点一定是黑色的;
· 5.从任意节点到子树上的叶子节点路径上的黑色节点数量相同;

  注意:Java实现的红黑树将使用 null 来代表空节点,因此遍历红黑树时将看不到黑色的叶子节点,反而看到每个叶子节点都是红色的。

红黑树处理

一、红黑树查找

  因为红黑树是一颗二叉平衡树,并且查找不会破坏树的平衡,所以查找跟二叉平衡树的查找相同:

· 1.从根结点开始查找,把根结点设置为当前结点;
· 2.若当前结点为空,返回null;
· 3.若当前结点不为空,用当前结点的key跟查找key作比较; · 4.若当前结点key等于查找key,那么该key就是查找目标,返回当前结点;
· 5.若当前结点key大于查找key,把当前结点的左子结点设置为当前结点,重复步骤2;
· 6.若当前结点key小于查找key,把当前结点的右子结点设置为当前结点,重复步骤2;

二、红黑树插入

  红黑树的插入和二叉查找树的插入一样,首先需要进行插入节点的查找,但相比较二叉查找树来说,红黑树的插入多了两个部分内容(这是红黑树保持平衡性的根本原因):

  · 对节点进行上色处理;

  · 对上色后的树进行相应的旋转操作。

  考虑插入节点对红黑树造成的影响,如果我们增加一个黑色节点,由于性质4限制每个子树上的黑色节点个数相同,加入黑色节点必定会违背此性质;若插入红色节点位置的父节点为黑色结点时,红黑树的黑色平衡没被破坏,不需要做自平衡操作。所以选择使用红色作为插入节点的颜色,此时只需要考虑性质5的情况(红色节点的子节点是红色节点的问题)。

旋转方式说明

  如下图示二叉查找树对A节点进行右旋操作,得到右边所示二叉查找树。
在这里插入图片描述

  下面详细列举插入的各种情况:

插入情况一:红黑树为空
此时直接把插入结点作为根结点,将插入节点设为黑色。

插入情况二:插入结点的父结点为红结点
根据性质2中所述,根节点一定是黑色,所以插入节点的父节点一定不是根节点。此情况中又分为两种情况:

  情况二 第一种: 插入节点的父亲和叔叔节点都是红色:

  如下图所示,插入节点为1,父亲节点为2,叔叔节点为8,父亲节点和叔叔节点均为红色,插入节点的爷爷节点一定为黑色,此时将父亲和叔叔节点颜色更改为黑色,这样6号节点的左右子树两边黑色个数一致,满足特征4。如果6号节点刚好为根结点时,那么也刚好满足性质2,那么树的红黑结构变为:黑黑红。而且,从根结点到叶子结点的路径中,黑色结点增加了。这也是唯一一种会增加红黑树黑色结点层数的插入情景。
在这里插入图片描述
  如果6号不是根节点,但此时有一个新的问题,6号节点被染成了黑色,对于6号节点的父节点来说,子树上的黑色节点数+1了,明显会造成不平衡的状态,所以需要把6号节点涂红,如下图所示操作。
在这里插入图片描述
  经过上图的处理后,此时6号节点变成了红色,当6号节点被染红之后,我们需要考虑的是,如果6号节点的父节点还不是根节点,那么他必然是红色的,这又违背了性质4,所以需要把6号节点作为调整节点,继续向上面进行判断。

  情况二 第二种: 叔叔节点不存在或者叔叔节点是黑色

  此时插入的节点是1,左边两个红结点,右边不存在,那么应该将红色接节点分给两边,并且因为是红色,肯定不会破坏树的平衡。

在这里插入图片描述
  上述的插入节点是父节点的左子节点,还有一种情况是,插入的节点是父节点的右子节点,此时需要先进行子节点与父节点的位置互换,然后再进行旋转。

在这里插入图片描述
在这里插入图片描述
同样的,如果是爷爷的右节点的右子树插入,使用左旋的方式进行处理。
在这里插入图片描述

三、红黑树删除

  与查找类似的,红黑树的删除也分为两个部分内容:
  · 查找待删目标;
  · 删除后进行平衡操作。
  红黑树删除操作是在二叉查找树删除操作的基础上进行平衡操作而来的,所以我们先来看一看二叉查找树的删除操作。

二叉查找树的删除

  二叉树删除结点找替代结点有3种情情景:

  · 1.要删除的节点正好是叶子节点,直接删除;
  · 2.只有左孩子或者右孩子,直接把这个孩子上移放到要删除的位置;
  · 3.有两个孩子,就需要选一个合适的孩子节点作为新的根节点,一般选择右孩子的最左节点作为新的根节点。

红黑树删除情况

情况一:被删除节点无子节点,且被删节点为红色
  此时直接将节点删除即可,红色叶子节点删除不会影响红黑树的平衡性质;在这里插入图片描述
情况二:被删除节点无子节点,且被删节点为黑色
  此时需要考虑的情况较多,在后面进行详细介绍;
在这里插入图片描述

情况三:被删除节点只有一个孩子节点,且被删除节点为红色节点
  让我们来回想一下前面所说的红黑树的性质4:“每个红色节点的两个子节点一定是黑色的”;也就是说红色节点后面只能跟黑色节点,那么此时红色节点的左右两个子树所包含的黑色节点数量就不一样了,所以这样的情况是不存在的,我们不需要考虑情况三;

情况四:被删除节点只有一个孩子节点,且被删除节点为黑色节点
  这种情况下,依据红黑树的性质5:“从任意节点到子树上的叶子节点路径上的黑色节点数量相同”;所以黑色节点只有一个孩子结点,那么这个孩子节点一定是红色的,不然这个黑色节点的左右两个孩子的黑色节点数量就不一样了。
  这时候的删除操作是:直接将黑色节点删掉!用唯一的孩子结点替换黑色节点的位置,并且将红色节点染黑。
在这里插入图片描述
情况五:被删节点有两个孩子,被删节点为黑色
  当被删节点有两个孩子节点时,需要找他的右孩子的最左节点,我们把它命名为后继节点,这个我们在二叉查找树的查找中进行过说明,不再赘述;此时我们用一个转换操作,使用后继节点数值替换删除节点,这时候我们只需要把后继节点删除即可。后继节点同样可能存在孩子节点,但一定只能是右孩子结点或者是没有孩子节点。
  现在再来分析一下这个后继节点的情况:
  · 如果后继节点就是删除节点的右孩子,后继节点是红色,同情况一的处理方式;后继节点是黑色,同情况二或者情况四的处理方式;
在这里插入图片描述
在这里插入图片描述

  · 如果后继节点是被删节点右子树上的节点,后继节点是红色,同情况一的处理方式;后继节点是黑色,同情况二或者情况四的处理方式;
在这里插入图片描述
在这里插入图片描述

情况六:被删节点有两个孩子,被删节点为红色
  被删节点是黑色或者是红色不影响结果,因为后继节点替换的时候继承了被删除节点的颜色,所以删除情况同情况五,但是有一点是需要注意的,如果被删除节点是红色节点,那么他的右孩子是后继节点的情况下,后继节点不可能是红色的,这是与情况五的区别之处。

基于上述六种情况的总结
  如果被删除的节点是一、四情况处理起来就非常方便,情况三不可能出现所以也不需要考虑,情况五、六最终也会转化为情况一、二。所以重点是第二种情况下,节点的删除操作以及树的平衡处理。

情况二的详细处理

  首先我们要明确为什么情况二比较复杂,删除一个没有孩子结点的黑色节点意味着什么?意味着没有孩子结点可以替换并且改成黑色,只有一个黑色节点直接删除就表明这里少一个黑色节点,影响了红黑树的第五条性质啊!!!那怎么行呢?我们要去找删除节点的兄弟节点或者父亲节点帮忙!下面来分四种情况讨论一下。

形式一:兄弟节点为黑色,并且兄弟节点有一个与其方向一致的红色子节点。

  如上图所示情况,左边因为删除了一个黑色节点,对父亲节点来说,我的左子树少了一个黑色,而现在我的右子树刚好有一个红色的节点,那我要把它变黑拿过来用,而且右子树少了一个红色节点并不会影响到红黑树的性质,可以放心的使用!

形式二:兄弟节点为黑色,并且星弟节点有一个与其方向不一致的红色子节点
在这里插入图片描述
  如上图所示情况,通过把兄弟节点右旋的方式,将形式二转换为形式一,再按照形式一的方式转化即可。

形式三:兄弟节点为黑色,并且兄弟节点没有红色子节点
  此时又出现了两种情况问题:
  · 一:父亲是黑色节点
  · 二:父亲是红色节点

首先来看第一种,父亲是红色节点的情况下!
  当兄弟节点没有红色孩子可以借用的时候,这时候我们该怎么办?那兄弟也别有了,大家都少一个吧!我少了一个黑色,把兄弟节点变成红色,同时把父节点染成黑色。这样子树又可以保持平衡了。
在这里插入图片描述
那么第二种,父亲节点也是黑色!
  这时候兄弟节点和父亲节点都比我多一个!这下糟糕了!没事,那就让兄弟节点陪我少一个吧,我们都平衡了,父亲把减少的黑色节点向上层传递解决吧!
  此时把父亲节点看做当前节点,因为父亲节点所在的子树上整体少了一个黑色节点,他要去上层保持平衡啦。去上层之后又可以转换为形式一二三,继续处理,如果一直是形式三也没关系,到了根节点之后,我们整个红黑树的黑色节点少了一个。
在这里插入图片描述

形式四:兄弟节点为红色,则父亲节点必为黑色
在这里插入图片描述
  终于到了最后一种,此时兄弟节点是红色的,也就是说限制了父亲节点,两个侄子节点都必须是黑色的,这时候父节点进行左旋操作,兄弟节点涂黑,父节点变红,情况回到形式一二三,到这里大家就很熟悉了!

红黑树的删除总结

  综上,红黑树删除后自平衡的处理可以总结为:

  1.自己能搞定的自己独立完成删除操作
  2.自己不能搞定的叫兄弟借一个红侄子
  3.兄弟都帮忙不了的,通过父母,找父母的兄弟朋友

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值