数据结构——红黑树的删除节点操作

1. 红黑树的删除操作过程分析

    1. 首先看一下普通搜索二叉树的删除操作,普通搜索二叉树删除结点找替代结点有3种情情景:

  • 情景1:删除结点无子结点,直接删除
  • 情景2:删除结点只有一个子结点
  • 情景3:删除结点有两个子结点

在这里有一个重要的思路:删除结点被替代后,在不考虑结点的键值的情况下,对于树来说,可以认为删除的是替代结点。

基于此,上面所说的3种二叉树的删除情景可以相互转换并且最终都是转换为情景1。

  • 对于情景2:删除结点用其唯一的子结点替换,子结点替换为删除结点后,直接删除
  • 对于情景3:删除结点用其子树中大于该节点的最小节点(该节点一定不存在左子节点)进行替换,如果替换节点有右子结点,那么相当于转换为情景2,否则转为为情景1。

所以,删除操作删除的结点可以看作删除替代结点,而替代结点最后总是在树末(找到的替代节点一定是树末节点,树末节点指的是子节点有一个为NIL的节点),红黑树也一样。

    2. 红黑树中删除节点时可能的情景:与普通搜索二叉树中删除节点不同,每当删除一个红黑树节点,就必须对红黑树进行平衡,但是删除红色树末节点一定是不影响平衡的。要明确一点,找到的替代节点一定是树末节点,也就是替代节点的左子节点一定为NIL节点,或左右子节点全为NIL节点。可能情景如下

webp

(1)替换节点是红色的:替换节点是红色的,删除后不影响红黑树平衡,所以直接替换删除即可。

(2)替换节点是黑色的,但其有一个子节点,该节点是红色右子节点,右子节点也不可能是黑色(不可能是红色左子节点):将右子节点改为黑色,再用右子节点顶替替换节点即可。

823435-20170812212618992-2016680440.png——>64357ae8fe87e786cd437aba49b37dcc260.jpg

(3)替换节点是黑色的,无子节点,而且是其父节点的左子节点,而且替换节点的兄弟节点是红色的:替换节点的兄弟节点是红色那么父节点一定是黑色,兄弟节点一定具有左右黑色子节点,而且是最底层节点。此时所需要做的就是将情景转化为情景1,思考一下如何在保证这部分子树红黑树性质的情况下,将R节点(替换节点)转化为红色节点。其实很简单,首先将S与P节点进行颜色互换,然后将S与P节点进行左旋操作,如下图所示;转换完成后,是否可以直接将P节点换为黑色节点,R与SL换为红色呢?这样就可以直接删除R节点了,如果SL节点无子节点那确实可以,但如果有子节点,那一定是红色子节点,如果SL节点换为红色就会违反红黑树性质。那么这种情况该如何处理呢?这时的情况就跳转到了情况4进行解决

98d619057f742e6ba669e867d80e42f6692.jpg——>7c57409ea3ccbad9324f11e86c86d1cef28.jpg——>90cd254377452c3e5d9ea7c2aa917f4055b.jpg

(4)替换节点是黑色,无子节点,而且是其红色父节点的左子节点,而且替换节点的兄弟节点是黑色的(兄弟节点下一定只有0-2个红色子节点):先直接将P节点与S节点进行一次左旋操作,保持节点颜色不变; 然后就可以直接删除替换节点R了; 如果S节点有红色左子节点,就很熟悉了,这正是红黑树的节点插入场景,将SL节点作为插入节点看待,进行一次插入操作的平衡即可。而其有没有红色右子节点就无所谓了。如下图所示

4339f1c9f1d17a2665946a61de5972326c3.jpg——>a58136ef6ed7b48bb6ea12f28ae0be0499a.jpg——>fa935be6d0f0d0ee7168c6b9c99658354ca.jpg

(5)替换节点R是黑色,无子节点,而且是其黑色父节点的左子节点,而且替换节点的兄弟节点是黑色的(兄弟节点下一定只有0-2个红色子节点):

如果兄弟节点含有左子节点或右子节点都还简单,如果只要通过变换保证S节点位置的节点有右子节点(如果只有左子节点SL,就将SL与S节点进行颜色互换,然后右旋,将S变为SL的右子节点即可;如果S节点本身就有右子节点就不需要变换了),然后对兄弟节点和父节点进行左旋处理,再对SR节点改为黑色就可以删除R节点了,如下图所示

a9301115ff4e690c007e100d65ddf8c9dc6.jpg对S节点和P节点左旋操作——>46926600d4ef8c1108df1cc81c429127a4c.jpg改色,删除R节点——>0f02f2c98f6e60e33a26cf04c02de2497bb.jpg

e8eac51db1ac046f932aad2bda53e3c76a5.jpg将S和SL节点换色,然后右旋——>c4c424c705dabe0460a175bd8096f638236.jpg再对SL节点和P节点左旋操作并将S节点改为黑色即可删除R节点

(6)替换节点R是黑色,无子节点,而且是其黑色父节点的左子节点,而且替换节点的兄弟节点是黑色的,且都无子节点:此时对这三个节点无论怎样变换都无法在删除R节点后让树平衡,所以此时需要向上探索保持平衡,也就是将P节点视作R节点向上平衡(所谓将P节点视作R节点也就是将不在乎P节点的左右子节点,就当做这是要被替换删除的一个树末节点,然后向上重新平衡),但并不是要删除P节点,而是通过一层层向上调整(向上调整也就是将P节点是为要被删除的节点,判断其为3,4,5,6中的哪一种情况,如果是3,4,5情况就可以直接调整平衡,但如果是情况6则继续向上一层调整)来重新让树达到平衡,达到平衡后在删除R节点

5f41db1711b60f2f62c62c908a31f3f3fa2.jpg

 

(7)对于替换节点是右子节点的问题,其实与上面操作相反就行了,而且实际上当替换节点是右子节点的情况下,其父节点就是删除节点。(想一想查找大于删除节点的最小节点查找算法,可以思考一下为什么)。

2. 具体实现代码

(情况太复杂,我也懒得实现了,网上有很多,但可能部分逻辑思想不太相同)

 

总结一下,实际上红黑树的具体实现,我们并不是一定要自己能把实现代码全部敲出来,很复杂,而且问题是你敲出来之后没有办法或者说很难通过调试来验证你的实现代码是否完全正确(其节点变化过程很难可视化的呈现)。但是我们必须要记住红黑树的5个性质,知道如何通过左旋与右旋来保持在删除插入时保证不违反这5个性质,如果强一点就记住典型的左节点情形的插入删除操作即可,右节点的情况是刚好相反的。

不用担心面试官会问红黑树具体实现代码,他要问你这个,直接说几种典型情况或者只说红黑树5个性质就行,如果非要你写实现代码直接不会,等到了后面他说“你还有没有什么要问的”的时候,你把这个问题反问他,你看看他能不能写出来。

转载于:https://my.oschina.net/ProgramerLife/blog/3082365

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值