算法导论 第13章 红黑树(图文详细解说)

本文详细介绍了红黑树作为一种自平衡二叉查找树,如何通过五条特性保证最坏情况下的操作时间为O(lgn)。文章分析了红黑树的节点定义、性质,以及如何通过旋转操作来维护红黑树的性质。同时,文章探讨了插入和删除节点后可能遇到的问题及解决方案,展示了如何通过变换确保红黑树性质的维护。
摘要由CSDN通过智能技术生成

1、二叉查找树的不足

二叉查找树的基本操作包括搜索、插入、删除、取最大和最小值等都能够在O(h)(h为树的高度)时间复杂度内实现,因此能在期望时间O(lgn)下实现,但是二叉查找树的平衡性在这些操作中并没有得到维护,其高度可能会变得很高,当其高度较高时,二叉查找树的性能就未必比链表好了,所以二叉查找树的集合操作是期望时间O(lgn),最坏情况下为O(n)。由于二叉查找树的高度问题,因而出现了红黑树,红黑树能够保证在最坏情况下的集合操作时间都是O(lgn),红黑树因其性能较好,有很多的应用,例如在C++STL中的一些性能较好的容器(如:set,map)都是利用红黑树作为底层数据结构来支撑的。


2、红黑树

红黑树也是一种二叉查找树,它拥有二叉查找树的性质,同时红黑树还有其它一些特殊性质,这使得红黑树的动态集合基本操作在最坏情况下也为O(lgn),红黑树通过给节点增加颜色和其它限制条件,使得红黑树中的某一节点到叶节点的任一路径不会比其它路径长两倍,因此可以保持树的平衡性。红黑树中节点包括五个域:颜色、关键字、左节点、右节点和父节点,并将没有子节点或父节点的指针指向一个 nil 哨兵节点,这个nil节点称着叶节点,也是外节点,其它包含关键字的节点叫着内节点。之所以要增加这样一个为空的外节点,是为了方便红黑树上的一些边界操作,特别是在删除节点的时候,这个nil节点就很有用了。

红黑树的节点定义为:

color key left right parent


2.1、红黑树的性质

红黑树的五个性质:

1、每个节点或者是红的,或者是黑的。

2、根节点是黑的。

3、叶节点(nil节点)是黑的。

4、如果一个节点是红的,则其孩子节点都是黑的。

5、对于任意节点,从该节点到其子孙叶节点(nil节点)的所有路径上包含相同数目的黑节点。

如下图:



那么为什么红黑树要定义这五个性质呢?其根本原因就是为了让红黑树能够自平衡,保证红黑树的高度为O(lgn),下面分别解释一下这五条性质:

性质1:定义了节点的颜色,是为后面的性质做铺垫的,不用细说。

性质2:一定要定义根节点为黑色,因为后面有性质4,定义根节点为黑色,则根节点的子节点的颜色就可以为红,也可以为黑,没有受到限制,否则如果定义根节点为红,则其子节点就只能为黑,就是实说红黑树的上两层节点颜色就定死了,这样显然让树不够灵活。

性质3:定义外节点nil节点为黑色,这时为红黑树操作边界情况时提供方便,大家在看到后面的删除节点的时候就会发现,如果定义为红色,若删除的节点在树的最底层,边界处理就能回考虑得更麻烦。

性质4:很重要,它说明了红黑树中如果有红节点,其子孙一定为黑节点,但是有黑节点,不一定要出现红节点,也就保证了整个红黑树中的任意路径上黑节点的个数至少是路径上节点总个数的一半,这为保证红黑树的高度任何时刻都为O(lgn)提供了重要依据。

性质5:就是为了让红黑树保持平衡,不出现普通二叉查找树可能出现的一边倒的情况。

因此红黑树的每个性质都是有特别意义的。


黑高度:从某个节点(不包括该节点)出发到达叶节点(nil节点)的任意一条路径上,黑节点的个数称为该节点的黑高度bh(x)。红黑树的黑高度就定义为根节点的黑高度。


引理:一颗有n个内节点的红黑树的高度至多为2lg(n+1)(可以利用节点的黑高度来证明),这也就保证了最坏情况下查找操作 O(lgn) 的时间复杂度。

这个引理很重要,它的得出就是由上面的五条性质支持的。下面我给出简单的证明:

设根节点为x,其黑高度为bh(x),则这棵红黑树节点最少的情况就是:高度h = bh(x) - 1,因为 bh(x) 包含了nil节点(为黑),所以路径上黑节点的实际数目应该是bh(x) - 1 ,在最长路径上没有红节点,全是黑节点,这时的节点总数是2^(h+1) - 1,也就是2^bh(x) - 1,所以红黑树的总结点数 n >= 2^bh(x) - 1,又因为红黑树的任意路径上黑节点个数至少是总结点个数的一半,所以bh(x) >= h/2(h为树的实际高度),所以n >= 2^(h/2) - 1,从而有h <= 2*lg(n+1),所以h = O(lgn)。

当然,这个引理也可以通过数学归纳法来证明,算法导论中就是如此。


红黑树在执行一些搜索,取最大最小值,取前驱后继节点等操作没有修改红黑树,因此跟二叉查找树上的操作相同,但是对于插入和删除操作,红黑树由于被修改了,必须执行一些额外的操作来维护其红黑树的性质,实际上这些额外的操作也不会改变插入和删除操作的时间复杂度,仍然为O(lgn)。


2.2、红黑树的旋转

为了维护红黑树的性质,需要执行一些红黑树特有的操作:旋转,包括左旋和右旋。

左旋:对节点x做左旋,必须保证它的右孩子y 不为nil节点,旋转以x到y之间的支轴进行,让y取代x的位置成为该子树新的根,而x成为y的左孩子,y原来的左孩子就成为x的右孩  子。时间复杂度为O(1)。



右旋:与左旋相反,对节点x做右旋,必须保证它的左孩子y不为nil节点,旋转以x到y的支轴进行,让y取代x的位置成为该子树新的根,而x成为y的右孩子,y原来的右孩子就成为  x的左孩子。时间复杂度为O(1)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值