红黑树删除

节点命名约定

D表示要被删除的节点。即:取 Delete 的首字母;
P 表示父节点。即:取 Parent 的首字母;
S表示兄弟姐妹节点。即:取 Sibling的首字母;
U表示叔伯节点。即:取Uncle的首字母;
G表示祖父节点。即:取 Grandfather的首字母;
L表示左树。即:取Left的首字母;
R表示右树。即:取Right的首字母;
Nil表示叶子节点。即所谓的空节点;注意:红黑树中的叶子节点与其他树中所述说的叶子节点不是同一概念。而且红黑树中的叶子节点(即:Nil节点)永远是被定义为黑色的。
DR表示要被删除的节点的右子树,即:右子节点;
SL表示兄弟节点的左子树,即:左子节点;

删除操作宏观分析

将红黑树内的某一个节点删除。需要执行的操作依次是:首先,将红黑树当作一颗二叉查找树,将该节点从二叉查找树中删除;然后,通过”旋转和重新着色”等一系列来修正该树,使之重新成为一棵红黑树。详细描述如下:

  • 第一步:将红黑树当作一颗二叉查找树,将节点删除。这和”删除常规二叉查找树中删除节点的方法是一样的”。
  • 第二步:通过”旋转和重新着色”等一系列来修正该树,使之重新成为一棵红黑树。

红黑树删除后平衡处理

在具体分析之前,再次列出红黑树的定义:
1) 任何一个节点非红即黑;
2) 树的根为黑色;
3) 叶子节点为黑色(注意:红黑树的所有叶子节点都指的是Nil节点);
4) 任何两个父子节点不可能同时为红色;
5) 任何节点到其所有分枝叶子的简单路径上的黑节点个数相同;

下面是几个图示说明:

《红黑树删除》

  根据红黑树的定义,被删除的节点D(即:上文所述的(Real)D节点)不论如何都一定有一个“右子树”,只是该右子树要不为非空树(即:真正存在的节点,不为Nil节点),要不就必为空树(即:D的两个子节点都为Nil)。下面称D的该右子节点(或称为右子树)为DR。

a) 被删除的D节点为红色。这种情况,则与D相关的颜色以及结构关系必然只有如下一种情况。

《红黑树删除》

  分析:因为D为红色,所以P必为黑色,同时DR不可能为红色(否则违反性质4)。同时由于性质5,则DR必为Nil,否则就D树来说,经过DR与不经过DR的路径的黑节点数必不相同。现在要删除D节点,只需要直接将D节点删除,并将DR作为P的左子节点即可。因此删除后,变成上图右侧所示。

b)被删除的D节点为黑色。此时情况会稍复杂些,具体又分析为:DR为Nil与DR不为Nil。根据性质5,如果DR不为Nil,则DR必为红色,且DR的两个子节点必为Nil。因此,此处先来分析DR不为Nil的情况(因为该情况比较简单)。而DR为Nil的情况,由后面的C)及其后内容再进行具体分析 。

如前所述,如果DR不为Nil,则D、DR必为如下情况:

《红黑树删除》

  分析:由于删除的D为黑色,删除后P的左子树的黑节点数必少1,此时刚好DR为黑色,并且删除后DR可以占据D的位置(这样仍是一棵二叉搜索树,只是暂时还不是合格的红黑树罢了),然后再将DR的颜色改为黑色,刚好可以填补P左子树所减少的黑节点数。从而P树又平衡了。因此,平衡处理后,最终变成上图右侧的图示。

c)被删除的D为黑色,且DR为Nil。
  如果DR为Nil,则删除D后,P的左子树黑节点数必定少1,纯粹想在P的左子树做文章来平衡P树是绝无可能的了。因此,必定需要其他分支的辅助来最终完成平衡调整。根据红黑树的定义,P会有一个右子节点,称为S子节点。此处又可细节分两种情况:黑S与红S。此处先讨论红S的情况。
  同时根据红黑树的性质,D、S、P、SL、SL的颜色关系必只有如下一种情况(因为此处探讨的是S为红的情况)。

《红黑树删除》

  分析:删除前P树的左、右子树的黑节点数平衡,删除后(即:上图右侧所示),经过DR分支的黑节点数将比通过S分支的黑节点数少1(未删除之前肯定是平衡的,左子树删除一个黑结点那肯定左右黑结点数目就不一致了)。此时,做如下操作:

  将P左旋转,再将P由黑色改为红色,将S由红色改为黑色,演变过程如下图示:

《红黑树删除》

    原文作者:zoyoto
    原文地址: https://www.jianshu.com/p/6753f8cdb7cc
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞