SGI-STL学习笔记之RB-tree part1

本文介绍了二叉搜索树的基本概念及其应用,包括查找、插入和删除操作,并详细探讨了平衡二叉搜索树(AVL树和红黑树)的平衡条件与调整方法。

<![endif]--> <![endif]-->

二叉搜索树

二叉搜索树 (binary search tree) ,可提供对数时间 (10garithmictime)3 的元素插入和访问。二叉搜索树的节点放置规则是:任何节点的键值一定大干其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。因此,从根节点一直往左走,直至无左路可走,即得最小元素:从根节点一直往右走,直至无右路可走,即得最大元素。

查找

5-4 所示的就是一棵二叉搜索树。要在一棵二叉搜索树中找出最大元素或最小元素,是一件极简单的事:就像上述所言,一直往左走或一直往右走即是。

插入

插人新元素时,可从根节点开始,遇键值较大者就向左,遇键值较小者就向右,一直到尾端,即为插人点。

删除

欲删除旧节点 A ,情况可分两种。如果 A 只有一个子节点,我们就直接将 A 的子节点连至 A 的父节点,并将 A 删除。如果 A 有两个子节点,我们就以右子树内的最小节点取代 A 。注意,右子树的最小节点极易获得:从右子节点开始 ( 视为右子树的根节点 ) ,一直向左走至底即是。

平衡二叉搜索树

所谓树形平衡与否,并没有一个绝对的测量标准。“平衡”的大致意义是:没有任何一个节点过深 ( 深度过大 ) 不同的平衡条件,造就出不同酌效率表现,以及不同的实现复杂度。 (每一种平衡树都有不同于其他平衡树的平衡条件,但是所有的平衡树都满足二叉搜索树的条件)

 

AVL tree(Adelson-Velskii-Landistree)

AVL tree 是一个“加上了额外平衡条件”的二叉搜索树。其平衡条件的建立是为了确保整棵树的深度为O(logN) 。直观上的最佳平衡条件是每个节点的左右子树有着相同的高度,但这未免太过严苛。 AVL tree 于是退而求其次,其平衡条件为:任何节点的左右子树高度相差最多 1 。这是一个较弱的条件,但仍能够保证“对数深度 (logarithmic depth) ”平衡状态。

 

由于只有“插入点至根节点”路径上的各节点可能改变平衡状态,因此,只要调整其中最深的那个节点,便可使整棵树重新获得平

 

假设该最深节点为 X ,由于节点最多拥有两个子节点,而所谓“平衡被破坏”意味着 X 的左右两棵子树的高度相差 2 ,因此我们可以轻易将情况分为四种:

1 .插人点位于 X 的左子节点的左子树——左左。

2 .插入点位于 X 的左子节点的右子树——左右。

3 .插入点位于 X 的右子节点的左子树——右左。

4 .插入点位于 X 的右子节点的右子树——右右。

情况 1 4 彼此对称,称为外侧 (outside) 插入,可以采用单旋转操作 (singlerotation) 调整解决。情况 2 3 彼此对称,称为内侧 (inside) 插入,可以采用双旋转操作 (doublerotation) 调整解决。

<![endif]-->

RB tree( 红黑树 )

RB tree 不仅是一个二叉搜索树,而且必须满足以下规则 ( 即平衡条件 )

1.  每个节点不是红色就是黑色

2 .根节点为黑色。

3 .如果节点为红,其子节点必须为黑。

4 .任一节点至 NULL( 树尾端 ) 的任何路径,所含之黑节点数必须相同。

根据规则 4 ,新增节点必须为红:根据规则 3 ,新增节点之父节点必须为黑。当新节点根据二叉搜索树的规则到达其插入点,却未能符合上述条件时,就必须调整颜色并旋转树形。

 

假设新节点为 X ,其父节点为 P ,祖父节点为 G ,伯父节点 ( 父节点之兄弟节点 ) S ,曾祖父节点为 GG 。现在,根据二叉搜索树的规则,新节点 X 必为叶节点。根据红黑树规则 4 X 必为红。所以,所有需要调整树形(或者颜色)的情况中, P 必定为红 ( 如此违反了规则 3 ,才会调整树形 ) 。根据规则 3 可知父子节点不能同时为红,所以 G 必为黑 ( 因为未插入新节点 X 之前该树为 RB tree ,必须遵循规则 3) 需要调整树形的情况仅仅与 X 的插入位置及外围节点 (S GG) 的颜色有关 ( 由,前面可知 X,P,G 的颜色已经推定 ) ,故有以下四种考虑:

 

状况 1: S 为黑且 X 为外侧插入。对此情况,我们先对 P,G 做一次单旋转再更改 P,G 颜色,即可重新满足红黑树的规则 3 。如图:

<![endif]-->

注意 ,此时可能产生不乎衡状态 ( 高度相差 l 以上 ) 。例如图中的 A B null D E 不为 null 。这倒没关系,因为 RB tree 的平衡性本来就比 AVL tree 弱。然而 RB tree 通常能够导致良好的平衡状态:是的,经验告诉我们, RB tree 的搜寻平均效率和 AVL tree 几乎相等。

                                                                                                                      

状况 2 S 为黑且 X 为内侧插入。对此情况,我们必须先对 P X 做一次单旋转并更改 G x 颜色,再将结果对 G 做一次单旋转,即可再次满足红黑树规则 3

<![endif]-->

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

STL 源码剖析》原文中的状况 3,4

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

状况 3 S 为红且 X 为外侧插入。对此情况,先对 P G 做一次单旋转,并改变 X 的颜色:此时如果 GG 为黑,一切搞定。如下图,但如果 GG 为红,则问题就比较大些,见状况 4

<![endif]-->

状况 4 S 为红且 X 为外侧插入。对此情况,先对 P G 做一次单旋转,并改变 X 的颜色、此时如果 GG 亦为红,还得持续往上做,直到不再有父子连续为红的情况。

<![endif]-->

备注:状况 3 4 STL 源码剖析原文中给出的情况。观察源码便知,此处与源码不符。参考《勘误 <STL 源码剖析 > 》,作者做出的解释十分牵强,并不具有任何说服力。《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

 

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

自己理解的状况 3,4

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

状况 3 S 为红且 X 为外侧插入,或者为内侧插入。对此情况,改变 P,G,S 颜色,此时如果 GG 为黑,一切搞定。如果 GG 为红,见状况 4

<![endif]-->

状况 4 S 为红且 X 为外侧插入,或者为内侧插入。对此情况,改变 P,G,S 颜色,此时如果 GG 为红持续往上做,直到不再有父子连续为红的情况。

<![endif]-->

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值