本章主要介绍两种通过扩张红黑树构造出的数据结构,一种是动态顺序统计树,另一种是区间树,之后介绍了如何扩张现有数据结构的一个通用方法。

动态顺序统计

:一个元素在集合线性序中的位置
顺序统计树:在红黑树上新增加1个size属性,这个属性包含了以x为根的子树(包括x本身)的(内)结点数,则该红黑树为顺序统计树,如下图所示:
算法导论第十四章数据结构扩张学习总结
查找具有给定秩的元素:找出T中的第i个小的元素,调用OS-SELECT(T,i),伪代码如下:
算法导论第十四章数据结构扩张学习总结
确定一个元素的秩:返回对T进行中序遍历后得到的线性序中x的位置,伪代码如下:
算法导论第十四章数据结构扩张学习总结
对子树规模的维护:对红黑树进行扩张后,插入、删除、左旋、右旋都要进行相应的修改,在维护后,插入删除复杂度仍为O(lgn),旋转的复杂度仍为O(1)。
插入函数:从新插入结点到根向上遍历的每个结点的size属性+1。
删除函数:从删除结点到根结点的路径上的每个结点的size属性-1。
旋转:仅会使两个结点的size属性失效,并且函数最后添加两行代码:①y.size=x.size②x.size=x.left.size+x.right.size+1。

如何扩张数据结构

扩张一种数据结构的四个步骤:
1、选择一种基础数据结构
2、确定基础数据结构中需要维护的附加信息
3、检验基础数据结构上的基本修改操作能否维护附加信息
4、设计一些新操作
定理 14.1(红黑树的扩张):设f是n个结点的红黑树T扩张的属性,且假设对任意结点x,f的值仅依赖于结点x,x.left和x.right的信息,还可能包括x.left.f和x.right.f,那么,我们可以再插入和删除操作期间对T的所有结点的f值进行维护,并且不影响这两个操作的O(lgn)渐近时间性能。

区间树

区间树是对红黑树扩张以便支持由区间构成的动态集合操作,集合中的每个元素x都包含一个区间int[x],x的关键字为区间的低端点low[int[x]],x中还包含一个新的域max[x],表示以x为根的子树中所有区间的端点的最大值,红黑树用到的关键字值是区间树的区间左端点值,下图所示为一棵区间树及其所表示的区间:
算法导论第十四章数据结构扩张学习总结
区间树构造步骤如下:
基础数据结构:选择红黑树,其中每个结点x包含一个区间属性x.int,关键字为区间的低端点x.int.low。这样对树进行中序遍历就可以按低端点的次序输出区间。
附加信息:每个结点除自身区间信息外,还包含一个值x.max,即以x为根的子树所有区间的端点的最大值。
对信息的维护:验证对max域的维护能在常规的插入、删除操作中完成,这样更新max域只需要O(1)时间。
新的操作:利用INTERVAL_SEARCH(T,i)新操作,找出树T中与区间i重叠的结点。
定理 14.2:INTERVAL_SEARCH(T,i)的任意一次执行,或者返回一个其区间与i重叠的结点,或者返回T.nil,此时树t中没有任何结点的区间与i重叠。

相关文章: