红黑树之二(删除节点)

红黑树的另一个重要的操作是删除节点,它也可以分为两步:

  1. 找到要删除的节点,并删除它
  2. 对树进行调整使得树满足红黑树的要求

一、删除节点

从排序树中删除节点的思路是一样的,首先找到要删除的节点,并做如下处理:

  1. 如果该节点不存在非空子节点,则直接删除它
  2. 如果该节点存在一个非空子节点,则用其非空子节点替换其位置即可
  3. 如果该节点有两个非空子节点,则可以找到该节点的前驱或者后继,然后更换两个节点的元素值,再将前驱或者后继当做被删除的节点(由于任意一个节点的前驱或者后继都必定至多只有一个非空子节点,因而删除这样的节点就可以按照前两种情形进行处理)

红黑树也采取了类似的思路,假设要删除的节点为A,则先找到节点A,然后:

  1. 如果节点A有两个非空子节点,则找到节点A的前驱(也可以是后继),然后记要删除的元素B=A的前驱
  2. 否则只要A有一个空子节点,就记要删除的元素B=A
  3. 记变量X为B的第一个非空子节点(先检查左孩子,后检查右孩子),如果B的两个孩子都为空,则记X为空
  4. 如果B和A不同,则将B的内容拷贝到A
  5. 删除节点B
  6. 如果被删除节点B的颜色为红色,则删除结束,否则从节点X处开始对删除节点后的红黑树进行调整

以下图为例:

《红黑树之二(删除节点)》

  • 如果要删除节点75,则A=75,B=85,X=NULL
  • 如果要删除节点25,则A=25,B=19,X=NULL
  • 如果要删除节点40,则A=B=40,X=NULL

显然,在这种处理方式下,如果B的颜色为红色,则删除它后删除操作即完成了,因为:

  • B是红色的,因而它不是根
  • B是红色的,它的父节点必然是黑色的,因而删除它不会引入两个红色的连续节点
  • B是红色的,而且它至多有一个非空子节点,因而删除它不会导致红黑树的任意路径上的黑节点数目变化

如果B的颜色为黑色,则需要从节点X处开始对删除节点后的红黑树进行调整。

二、红黑树删除后的调整

删除节点后的调整要根据N的不同情形来分情况处理(根据第一节的内容显然,这里的N指的就是第一节中的节点X)。假设删除节点后的树中,N的父节点为P,兄弟节点为S,兄弟节点的左孩子为SL,兄弟节点的右孩子为SR。需要注意的是空节点是有颜色的,它是黑色的。

2.1 N为根节点

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

2.2 N节点为红色

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

2.3 N、S、SL、SR、P都为黑色

如下图所示:

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

调整完后如下图所示:

《红黑树之二(删除节点)》

2.4 N、S、SL、SR都为黑色,P为红色

如下图所示:

《红黑树之二(删除节点)》 此时的处理很简单,只需要将S和P的颜色互换即可完成调整。

调整完可以得到下图:

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

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

此种情形如下图所示:

《红黑树之二(删除节点)》

此时的做法:

  1. 将以P为根的子树进行左旋
  2. 交换P和S的颜色
  3. 将SR的颜色改为黑色

则可以得到下图:

《红黑树之二(删除节点)》

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

因而调整完成。

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

此种情形如下图所示:

《红黑树之二(删除节点)》 此时的做法是:

  1. 首先对以S为根节点的子树进行右旋
  2. 然后交换S和SL的颜色,即S改为黑色,SL改为红色

则可以得到下图:

《红黑树之二(删除节点)》 由于节点SL的左孩子在旋转前后不变,而SL原来为红色,所以SL的左节点必然为黑色,因而旋转后,对于N节点来说,这就是情形5,按照情形5进行处理即可。因此总体上来说这种情形需要一次左旋,一次右旋。

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

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

《红黑树之二(删除节点)》 此时的做法是:

  1. 首选对以P为根节点的子树进行左旋
  2. 然后再将S和P的颜色互换,即修改S的颜色为黑色,P的颜色为红色

则可以得到下图:

《红黑树之二(删除节点)》 这就把该情形转化成了N为黑色,其兄弟为黑色的情形,再根据具体的情形参考情形3,4,5,6进行处理即可。

    原文作者:算法小白
    原文地址: https://blog.csdn.net/goodluckwhh/article/details/12718233
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞