数据结构之红黑树(三)——删除操作

删除一个节点同样有可能改变树的平衡性,而且,删除所造成的不平衡性比插入所造成的平衡性的修正更加复杂。

化繁为简是算法分析中一个常用的方法。下面我们将欲删除节点分为三大类:欲删除节点为叶子节点、欲删除节点只有一个子节点和欲删除有两个子节点。

而欲删除节点有两种可能的颜色,也需要分别对待。

为简化讨论,我们以欲删除节点在左侧的情况为例进行修正,如果欲删除节点在右侧,进行镜像地修正操作即可。


1. 欲删除节点是叶子节点

   1.1 欲删除节点为红色,父节点必为黑色,必无兄弟节点。

只有下图所示两种情况,带黄色边框的为欲删除的节点


将该节点直接删除即可,所在子树的黑色高度不变,不会影响红黑树的性质。

   1.2 欲删除节点为黑色,父节点可红可黑,必存在兄弟节点。

为什么说黑色节点必存在兄弟节点呢?如果一个黑色节点不存在兄弟节点,无论父节点是红是黑,则从该节点到父节点会比空子节点到父节点少一个黑色高度,所以这种情况是不存在的。

下面就可能存在的情况逐个分析:

       1.2.1 父节点是红色,则兄弟节点必为黑色

   与兄弟节点是否有左子节点相关,分为两种情况。      

(1)如果兄弟节点没有左子节点,修正策略如下:


上图中,虚线代表其连接的子节点可在可不在,对修正过程无影响。

 (2) 如果兄弟节点有左子节点,修正策略如下:


       1.2.2 父节点是黑色,则兄弟节点可红可黑

          1.2.2.1 兄弟节点为红色,则它必存在两个黑色子节点。

与左侄节点是否有子节点相关,分为三种情况。

(1)如果左侄节点有右子节点,修正策略如下:


(2)如果左侄节点没有右子节点,只有左子节点,修正策略如下:


这时,左侄节点就有了右子节点,再进行与上一种情况一样的修正。

(3)如果左侄节点为叶子节点,修正策略如下:


          1.2.2.2兄弟节点为黑色

与兄弟节点是否有子节点相关,分为三种情况。

(1)如果兄弟节点有右子节点,修正策略如下:


(2)如果兄弟节点无右子节点,只有左子节点,修正策略如下:

 

 

(3)如果兄弟节点既无左子节点,也无右子节点,如下图所示:


此时,依靠该子树的自身是无法解决的,因为该子树的黑色高度为2,如果将带黄色边框的节点删除,无论如何变换颜色、旋转都无法使该子树恢复黑色高度。

有两种解决思路:

(1)借助欲删除节点的祖父节点及祖父节点的子树来修正,只要祖父节点与祖父节点的另一颗子树中含有红色节点,就能通过颜色变化和旋转来使。但是,如果祖父节点与祖父节点的另一颗子树中的节点全为黑色:


这时,依靠该子树本身也是无法解决的,还需要借助更上层的节点。层层传递,直到根节点。如果到根节点还是不能解决,就需要采用另一种思路

(2)降低黑色高度。


但就这颗子树来说,确实是符合红黑规则的,但是,子树的黑色高度降低,会影响到整棵红黑树的黑色高度。


可以看到,变换之后,左子树的黑色高度为1,而右子树的黑色高度是2,违背了红黑规则。这时候就需要同时降低右子树的黑色高度,并层层向上传递,直到根节点,最终使整棵树的黑色高度降低。

但是,有的右子树是无法降低黑色高度的,比如:


上图中的右子树就无法降低黑色高度,但是这种情况下,右子树必存在红色节点,可以通过第一种思路解决。

总之,结合两种思路,总是是可以解决“黑三角”这种顽固问题的。

 

2. 欲删除节点只有一个子节点,该节点必为黑色,子节点必为红色

红色节点要么没有子节点,要么有两个黑色节点,所以该节点不可能为红色。

如果该节点只有一个黑色节点,则黑色的子节点到该节点的黑色高度与空子节点到该点的黑色高度不一致,所以子节点只能为红色。

综上,只有下图所示的两种情况会出现。


只需要将红色子节点涂黑,上移到被删除的节点位置即可。

 

3. 欲删除节点既有左子节点,又有右子节点。

红黑树也属于二叉搜索树,所以要先找到欲删除节点的后继节点。后继节点的寻找过程如下:从该点的右子节点开始,如果有左子节点则跳到左子节点,层层向下,直到某个子节点没有左子节点为止。实际上就是找到比欲删除节点的关键字值大的集合中的最小值。这部分内容在二叉搜索树中已经介绍过,不再赘述。

第一步,我们要将欲删除节点与后继节点中的数据对换,如此一来,节点的删除操作就转移到了后继节点上来了。

 

上图中,经过数据交换之后,没有改变任何节点的颜色,现在要删除的是带黄色边框的红色节点。前面已经论证,后继节点肯定是一个没有左子节点的节点,即是一个叶子节点或者只有一个右子节点的节点,而这两种情况的删除我们在之前已经分析过并给出了解决方法。

至此,红黑树所有可能出现的删除情况都已经讨论完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
红黑树是一种自平衡的二叉查找树,它在插入和删除节点时能够保持树的平衡。红黑树的概念可以参考。在Java中实现红黑树,可以按照以下步骤进行: 1. 首先将红黑树当作一颗二叉查找树,将新节点插入到适当的位置上。 2. 将插入的节点着色为"红色"。 3. 根据红黑树的特性,通过一系列的旋转和着色等操作,使树重新保持红黑树的性质。 具体的插入过程可以参考中提供的代码。在代码中,使用了左旋转、右旋转和颜色翻转等操作来重新平衡红黑树。 首先,如果节点的右子树是红色而左子树是黑色,可以通过左旋转操作将其变为左子树为红色,右子树为黑色的情况。 其次,如果节点的左子树和左子树的左子树都是红色,可以通过右旋转操作将其修正为上述情况。 最后,如果节点的左子树和右子树都是红色,可以通过颜色翻转操作将其修正为左子树和右子树都为黑色的情况。 在插入完节点后,需要将根节点的颜色设置为黑色,以确保红黑树的性质满足。 这样,通过以上的步骤,就能够实现对红黑树的插入操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java数据结构红黑树的真正理解](https://download.csdn.net/download/weixin_38622475/12770272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Java高阶数据结构红黑树](https://blog.csdn.net/qq15035899256/article/details/126678970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java数据结构——红黑树](https://blog.csdn.net/weixin_30699463/article/details/95256212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值