红黑树

本文详细介绍了红黑树的基本概念,包括其定义、增删结点的操作,特别是左旋和右旋。在增删结点过程中,通过着色和调整来维护红黑树的平衡。插入结点分为插入、着色、调整三个步骤,并提供了《算法导论》中的RB-INSERT-FIXUP伪代码,解释了三种不同情况的处理方式。

本文内容主要参考并基于《算法导论》第二版

引言

本文对红黑树的几个关键的知识点进行介绍,包括:

1)红黑树的定义

2)如何增删结点

 

红黑树的定义

红黑树是一种满足以下性质的二叉查找树:

1)所有的结点要么是红色的,要么是黑色的

2)根结点是黑色的

3)叶子结点是黑色的

4)如果一个结点是红色的,则它的两个孩子都是黑色的

5)对于一个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点

需要注意的是,红黑树首先是一棵二叉查找树,即它要满足二叉查找树的所有性质。红黑树还有一个比较常用的概念——黑高度,具体定义可查阅相关资料。

 

如何增删结点

一、首先需要理解增删结点要用到两个常用操作:左旋和右旋

如上图,从左到右是对x左旋——LEFT-ROTATE(T,x),从右到左是对y右旋——RIGHT-ROTATE(T,y)

理解左旋和右旋的一个关键点要知道操作的对象,严格来讲,单说左旋(右旋)是不对的,完整的说法应该是对某某左旋(右旋)。所以,对x左旋,是指把x和x的右孩子逆时针旋转;对x右旋,是指把x和x的左孩子顺时针旋转。

代码实现的时候需要注意,对每个结点,它的三个关键指针——父指针、左孩子、右孩子是否都已经正确处理。

另外需要注意的是,对红黑树的旋转不会改变结点的颜色。

 

二、插入结点

总的来说,插入结点分为三步(插入、着色、调整):

1)按照查找二叉树中插入结点的方法把新增的结点插入红黑树中

2)把新插入的结点着为红色

3)新插入的结点有可能破坏红黑树的5个性质,所以需要对此进行调整。

《算法导论》中把第三步叫做RB-INSERT-FIXUP(T, z) 。在这一步,算法会根据一些条件把结点z的状态分为三种情况,对每种情况做出不同的操作(改变颜色、左旋、右旋),直到满足红黑树的5个性质。其伪代码如下:

RB-INSERT-FIXUP(T, z)
 1 while color[p[z]] = RED
 2     do if p[z] = left[p[p[z]]]
 3           then y ← right[p[p[z]]]
 4                if color[y] = RED
 5                   then color[p[z]] ← BLACK                    ▹ Case 1
 6                        color[y] ← BLACK                       ▹ Case 1
 7                        color[p[p[z]]] ← RED                   ▹ Case 1
 8                        z ← p[p[z]]                            ▹ Case 1
 9                   else if z = right[p[z]]
10                           then z ← p[z]                       ▹ Case 2
11                                LEFT-ROTATE(T, z)              ▹ Case 2
12                           color[p[z]] ← BLACK                 ▹ Case 3
13                           color[p[p[z]]] ← RED                ▹ Case 3
14                           RIGHT-ROTATE(T, p[p[z]])            ▹ Case 3
15           else (same as then clause
                         with "right" and "left" exchanged)
16 color[root[T]] ← BLACK

对这段代码的理解要注意以下几点:

1)z始终指向红节点

2)z的父结点是红节点

3)3种情况的划分取决于:

   a. z的叔叔结点的颜色

   b. z是左孩子还是右孩子

4)左旋或右旋操作不会改变结点的颜色

5)代码的第2至14行的前提是z的父结点是左结点

以下是对三种情况的说明:

case1:z的叔叔y是红色的

case2:z的叔叔y是黑色的,且z是右孩子

case3:z的叔叔y是黑色的,且z是左孩子

由于z的父结点是左结点,所以要把case2向case3变换,当z的父结点是右结点时,就应该是把case3向case2变换。

 

三、删除结点

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值