第13章 数据结构的扩张
13.1 动态顺序统计
-
一棵顺序统计量树T通过简单地在红黑树的每个结点存入附加信息而成。在一个结点x内,除了原有的域,还包括 x . s i z e x.size x.size,这个域包含以结点x为根的子树的节点数: x . s i z e = x . l e f t . s i z e + x . r i g h t . s i z e + 1 x.size=x.left.size+x.right.size+1 x.size=x.left.size+x.right.size+1
-
查找具有给定秩的元素:OS-SELECT(x, i)
r = x.left.size + 1 if i == r return x elseif i < r return OS-SELECT(x.left, i) else return OS-SELECT(x.right, i-r)
-
确定一个元素的秩:OS-RANK(T, x)
r = x.left.size + 1 y = x while y != T.root if y == y.p.right then r = r + y.p.left.size + 1 y = y.p return r
-
对子树规模的维护:
给点每个结点的size域后,OS-SLELECT和OS-RANK能迅速地计算出所需的顺序统计信息。然而除非能够用红黑树上基本的修改操作对这些size域加以有效的维护,否则,就达不到期望的目的。- 第一阶段:插入结点:在寻找插入位置的过程中,所经路径上的结点size域都需加1
- 第二阶段:旋转:如果插入结点后,需要旋转某些结点,可以验证,可以在常数时间内更新相关结点的size域。
13.2 扩展数据结构
- 步骤
- 选择一种基础数据结构
- 确定基础数据结构中要维护的附加信息
- 检验基础数据结构上的基本操作能否维护附加信息
- 设计新的操作
13.3 区间树
-
闭区间是一个实数的有序对 [ t 1 , t 2 ] [t_1,t_2] [t1,t2],其中 t 1 < = t 2 t_1<=t_2 t1<=t2。
-
区间便于示占用连续时间的事件
-
我们可以把一个区间 [ t 1 , t 2 ] [t_1,t_2] [t1,t2]表示成一个对象 i i i,其中 l o w [ i ] = t 1 low[i]=t_1 low[i]=t1为低端点, h i g h [ i ] = t 2 high[i]=t_2 high[i]=t2为高端点。若两个区间 i i i与 j j j重叠,则满足区间三定律之一:
- i i i与 j j j重叠
- i i i在 j j j左边,即 h i g h [ i ] < l o w [ j ] high[i]<low[j] high[i]<low[j]
- i i i在 j j j右边,即$high[j]<low[i] $
-
区间树:一种对动态集合进行维护的红黑树。
-
操作:
- INTERVAL-INSERT(T, x)
- INTERVAL-DELETE(T, x)
- INTERVAL-SEARCH(T, i)
-
构造区间树:
-
基础数据结构
选择红黑树,其中每个结点x包含区间域x.int,关键字为区间的低端点x.int.low。这样对树进行中序遍历就可以按低端点的次序输出区间。 -
附加信息
每个结点除了区间信息之外,还包含一个值max[x],即以x为根的子树所有区间的端点的最大值。 -
对信息的维护
验证对max域的维护能在常规的插入、删除操作中完成:
x . m a x = m a x ( x . i n t . h i g h t , x . l e f t . m a x , x . r i g h t . m a x ) x.max=max(x.int.hight,x.left.max,x.right.max) x.max=max(x.int.hight,x.left.max,x.right.max),这样更新max域只需要常数时间。 -
设计新的操作
INTERVAL-SEARCH(T, i)x = T.root while x != T.nil and i dose not overlap x.int if x.left != T.nil and x.left.max >= i.low x = x.left else x = x.right return x
-
-