红黑树(三):插入·续

1. 插入(二):向一棵3-结点树中插入新键

本篇文章续:红黑树(二):旋转和插入

这种情况又可分为三种子情况:新键小于树的两个键,在两者之间,或是大于树中的两个键。每种情况中都会产生一个同时连接到两条红链接的结点,那么我们则需要修复它们。1

教材上长篇大论的分析这三种情况的文字就不Copy啦,图例1结合来讲解吧,更好理解啦哒:

在这里插入图片描述

通过上面的图例,我们可以发现,新键最小(case 2)和新键介于两者之间(case 3)可以转化到 新键最大(case 1)下面,也就是case 2 和 case 3可以转化到case 1。这点很重要,后续插入代码中的自平衡操作就是基于这里的观察。

2. 颜色转化(染色)

上面的case 1,我们看到了染色的作用。如果我们遇到一个结点,左右链接都是红色,我们可以把它们变成黑色,将这个结点变成红色,来修复定义2;同时,我们通过染色,将红链接向上进行转递。

那么,染色代码就非常简单啦:

/**
 * flip Colors
 *
 * @param reverse   true - set root's color to BLACK,
 *                  children RED ( up-down combing ),
 *                  false - set root's color to RED,
 *                  children BLACK ( bottom-up restoring )
 * */

private void flipColors( RedBlackTreeNode root, boolean reverse ) {
    root.color = reverse ? BLACK : RED;
    ( ( RedBlackTreeNode ) root.left ).color = reverse ? RED : BLACK;
    ( ( RedBlackTreeNode ) root.right ).color = reverse ? RED : BLACK;
}

这里大家先暂时忽略“boolean reverse“这个变量,对于插入,这个值默认为false;true是用来应对删除操作的。

最后再给一个染色的图例1

在这里插入图片描述

3. 根结点的颜色

那么根结点的颜色是什么呢?可红可黑么?答案是否定的,根结点的颜色一定是黑色的。假设我们修复到根结点,发现根结点是红色的,那么按照3-结点的定义,那么根结点之上一定还有一个黑结点,也就是根结点是属于一个3-结点,但是我们知道根结点之上是没有结点了的。所以我们每次再插入后都会将根结点设为黑色。

这也解释了结点定义中的性质2:根节点是黑色,如果你没有学过2-3树,那么对于根结点的颜色,只能解释成一种性质,如果学过2-3树,你就知道我们为什么需要设置根结点为黑色啦。

4. 插入(三):向树底部的3-结点插入新键

现在我们假设需要再树的底部的一个3-结点下加入一个新结点,那么我们再 1. 之中讨论的三种情况都会出现。

指向新结点的链接可能是3-结点的右链接(此时只需颜色转化,case 1),或是左链接(先右旋再染色, case 2),或是中链接(先左旋,然后右旋染色,case 3)

但修复的方法都是一样的,使用左右选和染色进行修复。让我们来看看图例1理解以下吧:

在这里插入图片描述

图例中给出了case 3的图解,其他两种情况相对简单,大家可以自己画一遍加深理解哒。

5. 红链接的向上转递

1) 插入(二),中我们说过,无论是case 2还是case 3都可以转化成case 1,而case 1会通过染色将红链接向上传递给父级,之后继续进行自平衡修复。所以这几种变化可以归纳到下面的图示中1

在这里插入图片描述

6. 构造轨迹图例

在这里插入图片描述

到此,插入的理论基础已经全部讲解完毕了,接下来,我们将看看如何用代码来实现红黑树的插入 - put()。


上一节:红黑树(二):旋转和插入
下一节:红黑树(四):插入实现
系列汇总:超详细!红黑树详解文章汇总(含代码)

7. 特别感谢

  1. 感谢 @SENNICHEN 制作系列文章封面图

8. 免责声明

※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~
※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;


在这里插入图片描述


  1. Algorithms 4th Edition ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值