详细红黑树操作通俗易懂讲解(插入与删除+图片通俗讲解)

红黑树学习总结

这篇文章是博主在学习红黑树底层逻辑之后做的总结,整篇以通俗易懂的讲解为大家分享红黑树的知识,如果大家想要更加直观的学习红黑树的相关操作,强烈推荐大家去看哔哩哔哩中的这个视频: 讲的非常好

为什么需要红黑树

平衡二叉树进行新增修改时常需要通过旋转来维持平衡,这样就会频繁改动二叉树,这个时候想出一个类似二叉树的结构,其中包含二叉树的某些特性,但又没有平衡二叉树那么严格,通过五条性质限制来建造这个树形结构,称为红黑树,在类似插入数据,删除数据时候减少像平衡二叉树那样的频繁修改

五条性质限制

  1. 根节点是黑色的
  2. 节点是红色或者黑色
  3. 叶子节点(外部节点,空姐点)都是黑色,特别注意,在红黑树中的叶子节点指的是底层的空节点null
  4. 红色节点的子节点都是黑色,红色节点的父节点都是黑色,从根节点到叶子节点不存在两个连续的红色节点
  5. 从任一个节点到叶子节点的所有路径都包含相同数目的黑色节点

特别注意在红黑树中的叶子节点指的是空节点null

从五条性质中可以总结出一个结论:红黑树保证最长路径不超过最短路径的二倍

为什么这么说,根据性质,首先最短路径和最长路径上的黑色节点数目是相同的,这个时候又因为不能有两个连续的红色节点,脑子中脑补一下,最长路径中的红色节点无法是最短路径的二倍,所以得出该条结论


红黑树的优越性需要在实际行动中体现,下边来介绍红黑树的操作过程

红黑树的操作

插入

首先像正常二叉树一样遍历到查询所在的位置进行插入:

当插入的时候父节点是黑色:满足红黑树的平衡条件,不进行处理

当插入的时候父节点是红色:就需要根据实际情况进行判断(根据父节点和祖父节点和叔叔节点的颜色进行判断)

  • 情况一:叔叔节点是红色的时候

这个时候祖父节点一定是黑色的,根据五条性质进行脑部
在这里插入图片描述
这个时候直接将祖父节点改变为红色,父节点和叔叔节点改变为黑色,这个时候局部就满足了红黑树的性质平衡,可能会出现祖父节点和他的父节点冲突都为红的问题,这个时候就要从底部向上进行持续更新直到整个红黑树达到平衡状态

  • 情况二:叔叔节点是黑色或者为空的情况

这种情况需要进行旋转和变色同时进行,根据位置的不同进行对应的旋转和变色操作

  1. 左左情况(新节点是其父节点的左节点,其父节点也是其父节点的左节点)
    在这里插入图片描述

此处进行一次右旋,因为此时在这个局部中,右路径的黑节点比左路径黑节点多1,进行一次右旋,父节点和祖父节点的颜色互换,就保证右路径的黑色节点的数目仍然不变,这个时候就再次保证了红黑树的平衡状态

  1. 右右情况(新节点是其父节点的右节点,其父节点也是其父节点的右节点)

和左左情况一样,只是进行一次左旋,同样将父节点和祖父节点的颜色进行互换,再次达到红黑树的平衡

  1. 右左情况(新节点是父节点的右节点,而父节点是祖父节点的左节点)
    在这里插入图片描述

先将父节点进行一次左旋,然后整体就成了左左情况了,再次进行右旋就再次达到了红黑树的平衡状态

  1. 左右情况(新节点是父节点的左节点,而父节点是祖父节点的右节点)

先将父节点进行一次右旋,然后就成为了右右情况,这个时候对整体进行一次左旋,就达到了红黑树的平衡状态


删除

在红黑树中进行删除基本步骤分为两步

  1. 像二叉树一样找到待删除的节点进行删除
  2. 删除后维持红黑树的平衡状态

在正常删除之前进行正常删除的情况判断

  1. 节点没有孩子,直接删除
  2. 只有左子树/只有右子树 - 直接节点的左右子树进行替代
  3. 删除节点左右子树都有,就是在左子树中找一个最大的或者是右子树中找一个最小的进行替代

在删除的时候根据删除位置的不同以及颜色的不同面临更加复杂的情况,我们来进行分析

情况一:删除节点是叶子节点

当叶子节点是红色状态,直接删除就行了,并不会影响到红黑树的整体状态

当叶子节点是黑色状态(复杂重点我们需要根据他的兄弟节点进行判断

大家不用疑惑兄弟节点为空的节点情况,这种情况不存在,因为如果为空就会违反性质5

1. 兄弟节点为黑色的时候(根据叔叔节点的孩子颜色进行判断)

1.1 兄弟节点的孩子种至少有一个红色节点

1.1.1 LL型(兄弟节点是父节点的左节点,红色节点是兄弟节点的左节点)

删除叶子节点12:
在这里插入图片描述

这种情况,首先将红色节点颜色转换为兄弟节点的颜色,兄弟节点转换为父亲节点的颜色,对父亲节点进行右旋,将父亲节点转换为黑节点,如下所示:

在这里插入图片描述

1.1.2 RR型(兄弟节点是父亲节点的右节点,红色节点是兄弟节点的右节点)

删除节点2:
在这里插入图片描述

节点r转换为s的颜色,节点s转换为p节点的颜色,对节点p进行左旋,并转换为黑节点,如下图所示:

在这里插入图片描述

1.1.3 LR型(红色节点是兄弟节点的右节点,兄弟节点是父亲节点的左节点)

删除节点12:

在这里插入图片描述

首先将红色节点转换为父亲节点的颜色,然后将兄弟节点进行左旋,再对父亲节点进行右旋,最后将父亲节点颜色转换为黑色,如下图所示:

在这里插入图片描述

1.1.4 RL型(兄弟节点是父亲节点的右节点,红色节点是兄弟节点的左节点)

删除节点5:
在这里插入图片描述

首先将r节点颜色转换为p节点的颜色,然后对兄弟节点s进行右旋,再对父亲节点p进行左旋,最后改变p的颜色为黑色,如下图所示:

在这里插入图片描述

1.2 兄弟节点的孩子都为黑色

删除节点9:

在这里插入图片描述

删除节点9之后,将兄弟节点变为红色,得到如下图示:
在这里插入图片描述

这个时候对于8来说左右满足性质5,但是对树的整体而言,根节点的左子树黑节点比右子树的黑节点数目少1,这个情况分为两种情况:

第一种: 父亲节点为黑色节点的时候,将红色节点6的状态上移,把父亲节点看作是红色节点,相当于对于根节点15而言删除它的左叶子黑节点,这个时候,还是按照规则看他的兄弟节点,属于RR型状态,进行颜色转换和旋转,如下图所示:

在这里插入图片描述

这样红黑树又恢复到了平衡状态

第二种: 父亲节点为红色的时候,将父亲节点8改变颜色为黑色节点,完成红黑树的平衡

特殊情况:如果父亲节点是根节点,这个时候无论父亲节点是黑节点还是红节点,都将根节点转换为黑色节点,就达到平衡状态

2. 兄弟节点为红色的时候

删除节点21:

在这里插入图片描述

首先兄弟节点和父亲节点进行颜色转换,父亲节点朝着删除节点方向进行旋转,旋转完成之后如下图所示:

在这里插入图片描述

这个时候节点17和兄弟节点不满足性质5,继续进行旋转,相当于删除节点d,此时s节点两个孩子都为黑节点,这个时候将s转化为红色节点,由于父节点p为红色节点,这个时候直接将p节点转换为黑色节点,如下图所示:

在这里插入图片描述

情况二:删除节点只有一个子节点

这种情况只有一种情况,那就是节点是黑节点,其子节点是红色的

这种情况直接删除节点,将子节点转换为黑色替换到被删除位置

为什么呢?如果节点是黑的话只有一个子节点是黑节点那么这个局部就会造成性质5的违背,如果过是红节点子节点为黑这样也会违背性质5,所以说只有一个节点的删除只存在这一种情况

情况三:删除节点有两个子节点

和普通的二叉树的删除一样,当删除节点有两个子节点的时候,找到前驱中的最大节点或者找到后继中的最小节点,然后按照前面所讲的规则进行处理,达到红黑树的平衡状态。


红黑树的优势

大家可能会问道,上边的操作这么复杂,他比平衡二叉树到底强在了哪里?我也有疑问

比如说二叉搜索树和红黑树同时增加一条数值递增的数据,对于二叉搜索树就会一直增加,可能最后会造成一条链表,这样就会导致后序的插入,删除,查询的时间复杂度达到O(N),同样,红黑树插入这一条数据,根据颜色的转换和旋转,将树转化为平衡状态,这样树的插入,删除,查询的时间复杂度仍然是O(logn),红黑树的最大高度最多为2log(n+1),普通二叉树的高度最大是n


HashMap底层红黑树的转换

当链表长度达到8,会将链表转换为红黑树,当链表长度下降到6的时候会将红黑树转化为链表

  • 链表转化为红黑树
  1. 创建一个红黑树对象
  2. 将链表中的数据逐个插入到红黑树中,在插入过程中,红黑树会自动保持他的平衡性
  3. 更新桶中的引用,指向新的红黑树对象
  • 红黑树转换为链表
  1. 遍历红黑树将红黑树中的数据插入到链表中
  2. 更新桶中的引用,指向新的链表对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值