红黑树节点的删除操作

本文详细探讨了红黑树节点删除的操作,包括删除后如何调整以保持红黑树的特性。主要分为删除操作和双黑处理两部分,涉及不同颜色组合的节点删除情况及对应的调整策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    红黑树节点的删除操作比其节点的插入操作要麻烦很多,自己在这个知识点的学习当中也困惑很多,这篇博客是自己在红黑树学习当中的一些自我理解与总结。

红黑树节点的删除操作分为两大步骤:

(1)找到删除的节点并且删除它:因为在删除红黑树节点时,往往要删除x,但并不是要删除X那个节点,而是将红黑树的一个适当的节点进行删除,用这个适当的节点的值去填充要删除的x这个值。

(2)节点删除后对红黑树的调整,使其满足红黑树的特有条件。

一。找到删除的节点并且进行删除

        首先要了解,(1)如果删除的节点是黑色,且其左右节点都为黑色,要进行节点删除后的调整(双黑操作)。(进行调整是因为要满足红黑树的从某个节点出发其左右子树中的黑色节点数目相等)

                           (2)如果删除的节点为红色,则直接删除,不会对红黑树结构造成影响不需要进行调整。

 删除情况分为3种情况:

在看删除情况时建议先看看博客后面总结的双黑操作

       (1)删除点为叶子节点

                 (1)删除点为红色,直接删除


红黑树删除操作 - 枫叶 - 枫叶


                删除结点0,结点0为红色结点,直接删除即可                

             (2)删除点为黑色,又因为在红黑树中默认空节点为黑色的,所以要进行双黑操作。

                           例子1

红黑树删除操作 - 枫叶 - 枫叶

 图21
                     删除结点18,结点18为叶子结点,且为黑色,删除后出现双黑,属于双黑处理的第一种情况的(2),处理后

红黑树删除操作 - 枫叶 - 枫叶

图22



 
                                         例子2

  

红黑树删除操作 - 枫叶 - 枫叶


 


                
               删除结点15,结点15为叶子结点,且为黑色,删除后出现“双黑”,进行双黑操作。属于后面介绍的双黑处理的第二种情况的第(2)个,得到

红黑树删除操作 - 枫叶 - 枫叶


       (2)删除点只有一个非空子节点

                 (1)删除点为红色,直接删除


                 (2)删除点为黑色,其非空子节点为黑色,直接删除这个删除点,并且将其子节点提升到该删除点

                            的位置。

                 (3)删除点为黑色,其非空子节点为红色,删除这个删除点,将其子节点提升到该删除点的位置,

                           并且将那个非空子节点改为黑色。

红黑树删除操作 - 枫叶 - 枫叶


               删除结点11,结点11有一个非空子结点,为第二种情况的(3)情况,删除11 后,将其非空子结点着为黑色
 

红黑树删除操作 - 枫叶 - 枫叶


       (3)删除点右两个非空子节点                

                    将删除点的后继节点和这个删除点进行替换,然后观察新的删除点的位置满足上面(1)(2)情况的哪种,对其进行操作即可。

由于第三种情况与第一种第二种情况有着千丝万缕的关系,下面举的例子比较综合。

                        例子1.

红黑树删除操作 - 枫叶 - 枫叶
            删除1结点,1结点有两个非空子结点,调整为叶子结点,与其后继结点2进行值 交换;此时,1结点只有一个非空子结点,则删除1结点后,将其子结点着为黑色,处理结果如图13
红黑树删除操作 - 枫叶 - 枫叶

                   例子2.

红黑树删除操作 - 枫叶 - 枫叶

        删除结2,结点2有两个非空子结点,与后继结点3值交换;后继结点为黑色,删除2后,出现双黑;用第一种方法的(2)情况来解决


         结果为:

红黑树删除操作 - 枫叶 - 枫叶

            



二、红黑树删除后的调整(双黑处理)

删除节点后的调整要根据N的不同情形来分情况处理。假设删除节点后的树中,N的父节点为P,兄弟节点为S,兄弟节点的左孩子为SL,兄弟节点的右孩子为SR。需要注意的是空节点是有颜色的,它是黑色的。

 N为根节点

这种情形非常简单,直接将其修改为黑色即可。因为如果N原来是黑色,则这样做不会改变其性质,如果原来为红色,我们需要保持红黑树的性质,也要把它修改为黑色。

 N节点为红色

空节点不可能是红色的,而按照我们删除时所采取的算法,此时的N必定为被删除的黑色节点的唯一非空子节点,并且在删除后它替代了被删除节点的位置,那么要恢复红黑树的性质就非常简单,只要将其颜色修改为黑色即可。

(1)(1)N、S、SL、SR、P都为黑色(删除节点n的兄弟节点为黑色,且其兄弟节点的子节点都为黑)

如下图所示:

此时的做法是将S的颜色修改为红色,则通过S和通过P的路径上的黑色节点数目变得相同了,但是通过N的路径比不通过N的路径都少了一个黑色节点,因而需要将P节点看做N节点重新执行调整算法。

调整完后如下图所示:

(1)(2) N、S、SL、SR都为黑色,P为红色(删除节点n的兄弟节点为黑色,且其兄弟节点的子节点都为黑,但是其父节点为红)

如下图所示:
此时的处理很简单,只需要将S和P的颜色互换即可完成调整

调整完可以得到下图:

在S和P的颜色互换后,P成为了黑色,它为经过节点N的路径添加了一个黑色节点从而补偿了被删除的黑色节点;同时由于S的两个孩子都为黑色,因而S改为红色也不会导致两个连续的红色节点,由于S的黑色只是上移到了其父节点P上,因而经过S节点的路径的黑色节点数目也不会发生改变。

(2)(1) N是黑色,S是黑色,SR是红色(考虑N为P的左孩子的情形,N为P的右孩子的情形与之对称)

        (删除节点n为黑,其兄弟节点为黑,但是兄弟节点的两个子节点有红色节点,这里不关心父节点的颜色)

                       (1)是兄弟节点的子节点中的远离删除节点n的那个子节点为红色

此种情形如下图所示:



此时的做法:
  1. 将以P为根的子树进行左旋
  2. 交换P和S的颜色
  3. 将SR的颜色改为黑色
则可以得到下图:

  • 对原树中P的父节点来说,调整前后其孩子的颜色没有改变,而N,P,S,SL,SR在调整之后也没有出现连续的红色节点,因而不允许出现连续红色节点的性质没有被违背。
  • 对于N,P,S,SL,SR这几个节点组成的树的部分来说,调整后它们给经由节点N的路径贡献的黑色节点数目比调整前增加了一个,这恰好补偿了删除黑色节点的效果;而对于不经过N节点但是又经过其它几个节点中的任意一个的路径来说,它们贡献的黑色节点数目不变。
因而调整完成。

(2)(2) N是黑色,S是黑色,SL是红色,SR是黑色(考虑N为P的左孩子的情形,N为P的右孩子的情形与之对称)

        (删除节点n为黑,其兄弟节点为黑,但是兄弟节点的两个子节点有红色节点,这里不关心父节点的颜色)                    (2)是兄弟节点的子节点中的离删除节点n比较近的那个子节点为红色          

此种情形如下图所示:

此时的做法是:

        1.针对s做一次右旋转,结果使双黑结点的近侄子成n结点新的兄弟;

        2.将新兄弟结点着为双黑结点的父结点的颜色,父结点着为黑色,

        3。再针对父做一次左旋转

则进行1.2不操作后可以得到下图:
由于节点SL的左孩子在旋转前后不变,而SL原来为红色,所以SL的左节点必然为黑色,因而旋转后,对于N节点来说,这就是情形5,按照情形5进行处理即可。因此总体上来说这种情形需要一次左旋,一次右旋。这里第三步操作没有画出来

(3) N是黑色,S为红色(考虑N为P的左孩子的情形,N为P的右孩子的情形与之对称)

                 (双黑节点n的兄弟节点为红色【这里注意只要满足这一条件,则其父节点和其兄弟节点的左右节点就都为黑,因为要满足红红不相连的规则】)

由于S为红色,所以P,SL,SR都必定为黑色,如下图所示


此时的做法是:
  1. 首选对以P为根节点的子树进行左旋
  2. 然后再将S和P的颜色互换,即修改S的颜色为黑色,P的颜色为红色
则可以得到下图:

这就把该情形转化成了N为黑色,其兄弟为黑色的情形,再根据具体的情形参考情形3,4,5,6进行处理即可。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值