数据结构的扩张
本章内容:
一 动态顺序统计
二 如何扩张数据结构
三 区间树
一 动态顺序统计
参照:红黑树
1. n个元素集合中的第 i 个顺序统计量就是简单地规定为该集合中的具有第 i 小关键字的元素。对于一个无序的集合可以在O(n)的时间内确定任何的顺序统计量。这里修改一下红黑树使得可以在O(lg n)时间内确定任何的顺序统计量。
2. 顺序统计树:在原先红黑树的每个结点x加入属性size , 表示以x为根的子树的总结点数(包括x),定义哨兵大小为0,即T.nil.size = 0. 有等式:
x.size = x.left.size + x.right.size + 1
3. 为了使关键字可以相同,定义一个元素的秩为在中序遍历树时输出的位置。
4. 对具有给定秩的元素的检索,过程OS-SELECT返回一个指针,指向以x为根的子树中包含第 i 小关键字的结点,运行时间为O(lg n).
5. 确定一个元素的秩,过程OS-RANK返回对T中序遍历对应的线性序中 x 的位置,运行时间O(lg n)
6. 对子树规模的维护,因为加入了size属性,对原先红黑树的操作就要能够维护size属性。
以插入操作为例,红黑树的插入操作包括2个阶段。第一是从根开始沿树下降,将新结点插入作为某个已有结点的孩子;第二是沿树上升,做一些变色和旋转操作来保持红黑树的性质。
在第一阶段中,只要对由根至叶子的路径上遍历的每个点的size属性加 1 即可。
在第二阶段中,对红黑树结构的改变仅仅是由旋转所致,旋转次数至多为2。每次旋转会使2个结点的size属性失效。先看一下之前的左旋代码:
只需对其增加2行即可:
如图说明了这2行代码是如何实现的:
右旋的操作还有删除结点的操作具体做法类似。
二 如何扩张数据结构(略)
三 区间树
1. 闭区间为有序数对[t1, t2], 把区间表示为一个对象 i , i.low = t1 , i.high = t2 , 这样两个区间a 和 b肯定满足区间三分律:
a和b重合 a在b的左边 a在b的右边
2. 区间树:是一种红黑树,每个结点x包含一个区间x.int , 支持一下操作:
INTERVAL-INSERT(T, x):将包含区间属性int 的元素x插入
INTERVAL-DELETE(T, x):删除元素x
INTERVAL-SEARCH(T, i):返回元素x的指针,并且x.int 与 i 重叠,若不存在返回T.nil.
例子:
如图是10个区间的集合,用中序遍历树会得到左端点从小到大的排列。每个结点包含区间属性x.int , 且x的关键字为x.int.low.此外每个结点x还包含一个值x.max,是以x为根的子树中所有int.max的最大值。
3. SEARCH操作: