红黑树添加元素和删除元素后的处理逻辑分析

以下代码和实现思路来源于B站视频“恋上数据结构与算法”,地址: https://www.bilibili.com/video/BV13v41167ix?

红黑树的性质

1.节点是RED或BLACK
2.根节点是BLACK
3.叶子节点(外部节点,空节点)都是BLACK
4.RED节点的子节点都是BLACK
4.1 RED节点的parent节点都是BLACK
4.2 从根节点到叶子节点的所有路径上不能有2个连续的RED节点
5.从任意节点到叶子节点的所有路径都包含相同数目的BKACK节点
红黑树通过将BLACK节点与它的RED子节点合并够转化为4阶B树。
空节点的颜色为BLACK

红黑树的添加元素分析

如下图所示是一棵以55为根节点的红黑树,在红黑树上添加同在平衡二叉树上添加元素类似,只能添加到叶子节点(添加的节点默认为RED)。对于红黑树添加节点的处理分为三种情况:
1.节点添加后它的父节点为BLACK
如图中在46的左边添加元素或在76的右边添加元素。对于这种情况节点添加后直接满足红黑树的5条性质,不做任何改动。
2.父节点为RED,叔父节点为RED
如图中在17节点下添加10或20,或在33节点下添加30或36的情况。对于这种情况,类似于4阶B树上溢,以下图添加节点10为例,添加后导致红黑树不再满足以上5条性质中4和5,处理办法是将添加节点(10)的祖父节点(25)作为分隔,使得其祖父节点(25)的左右子树各成一颗红黑树,为使其祖父节点(25)的左右子树各成一颗红黑树,需要将添加节点(10)的父节点(17)染成BLACK(性质2),同时将添加节点(10)的叔父节点(33)染成BLACK。对于祖父节点(25),需要将它先染成RED(添加节点默认为RED),再将其作为添加节点进行同样的处理(即对它而言,要重复添加节点的操作,对其父节点判断是否为红色,是红色在判断其叔父节点是否为红色,等等,即进行递归)
3.父节点为RED ,叔父节点(父节点的兄弟节点)为BLACK
如图中在50下面添加左右节点或在72下面添加左右节点都是这种情况,对于这类情况,需要对节点进行旋转(同AVLTree一样),旋转分为4中情况:
3.1 LL型:如图中添加60。需要对grandparent(76)进行右旋转,即让parent(72)成为根节点,grandparent(76)成为parent(72)的右子节点,同时grandparent(76)的左指针域指向原来72的右指针域指向的节点。并且对节点颜色进行调整,将parent(72)改为BLACK,将grandparent(76)改为RED。注意:这里旋转对涉及到的节点的parent域进行更改,让72的右孩子(如果有的话)的parent域指向76,让72的parent域指向原76的parent,让76的原parent节点的对应域(left域或right域)指向72,让76的parent域指向72.
3.2 RR型:如图中添加52。需要对grandparent(46)进行左旋转,将50改为黑色,将46改为红色,让50作为该子树的根节点,46做50的左孩子
3.3 LR型:如图中添加74,需要先对parent(72)进行左旋转,再让grandparent(76)进行右旋转。
3.3 RL型:如图中添加48,需要先对parent(50)进行右旋转,再让grandparent(46)进行左旋转。
在这里插入图片描述

红黑树的删除元素分析

如下图所示,在对红黑树元素的删除中,实际删除的节点一定为叶子节点,例如删除节点25,实际实现中是先找到它的后继节点(也可以是前驱)将后继节点的element域的值赋给25,再删除其后继节点(或前驱)。所以,在节点的删除中有三种情况:
一.实际删除节点为红色
如图中17、33、50、72
二.实际删除节点为黑色,它的左指针域或右指针域有元素
如图中46、76
三.实际删除节点为黑色叶子节点
如图中88在这里插入图片描述

情况一

(1.实际删除节点为红色)

判断方法:

对于这种情况的判断是被删除节点为红色。

处理方法:

节点删除后不需要做任何处理,因为删除该节点后红黑树仍然满足5条性质

情况二

(2实际删除节点为黑色,它的左指针域或右指针域有元素)

判断方法:

对于这种情况的判断是用于取代被删除元素的位置的节点颜色为红色(当节点被删除后它的非空域会取代它的位置,如图1中删除46或76,它们的位置会分别由50和72取代,这用于取代它们的元素是红色)。

处理方法:

对用于取代的节点是红色节点,将该节点染成黑色。

情况三

(3实际删除节点为黑色叶子节点)

判断方法:

删除的节点是黑色,且用于取代的节点(可能没有)是黑色(空节点为黑色)。

处理方法:
情况1:

该节点的父节点为红色兄弟节点是黑色,且兄弟节点至少有一个红色子节点。如图二中删除88时的几种情况。
在这里插入图片描述

情况1处理方法:

以图二中三幅图中第一幅为例,删除88后88的位置空出,该位置下溢,需要向兄弟节点位置(76和78)借一个节点。即将76左旋转,再将80右旋转,并将78染成原来80的颜色,将80染成黑色,即解决下溢问题。红黑树恢复5条性质。
在这里插入图片描述

情况2:

该节点的父节点为红色兄弟节点是黑色,且该节点的兄弟节点没有红色子节点。如下图三中第一步时的情况。

情况2处理方法:

由于兄弟节点不能借一个节点去恢复88的位置,就将其父节点(80)与兄弟节点合并,如图三中第三步,将80染黑,将76染红,即可使其恢复符合红黑树的性质。
在这里插入图片描述

以上已经分析了在删除黑色节点的时候,其父节点为红色的所有情况,现在分析其父节点为黑色的情况。

情况3:

该节点父节点为黑色,兄弟节点为黑色。(兄弟节点不能借一个过去,而父节点与兄弟节点合并又会导致父节点位置失衡)。

情况3处理方法:

如图四所示,在删除80右边的黑色叶子节点88后,将80与76合并,并将76染成红色。此时原来80所在位置空出,该位置失衡。将该节点作为被删除节点,以该位置作为参数递归调用恢复红黑树的函数。由递归过程处理。
在这里插入图片描述

情况4:

该节点父节点为黑色,兄弟节点为红色。也就是说兄弟节点与父节点在同一层。如图五第一步所示。

情况4处理方法:

让被删除节点(88)的兄弟节点(55)的右孩子节点(76)作为该节点(88)的兄弟节点。即对其父节点(80)做右旋操作,结果如图五第二步所示。此时该情况变为情况2.

在这里插入图片描述
以上分析全是是对删除右黑色叶子进行的分析,删除左黑色叶子的逻辑与其类似, 所有操作取反即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值