第14章《数据结构的扩张》:如何扩张数据结构

如何扩张数据结构

对基本数据进行扩张以支持一些附加功能,在算法设计过程中是相当常见的。所以扩张一种数据结构大概可以分为如下4个步骤:

  • 选择一种基础数据结构
  • 确定基础数据结构中要维护的附加信息
  • 检验基础数据结构上的基本修改操作能否维护附加信息
  • 设计一些新操作

以上仅作为一个一般模式,大多数的设计工作都包含试探和纠错的成分,过程中所有步骤通常可以并行进行

区间树

扩张红黑树来支持由区间构成的动态集合上的一些操作。闭区间(closed interval)是一个实数的有序对 [ t 1 , t 2 ] [t_1,t_2] [t1,t2],其中 t 1 ≤ t 2 t_1\le t_2 t1t2,区间 [ t 1 , t 2 ] [t_1,t_2] [t1,t2]表示了集合 { t ∈ R : t 1 ≤ t ≤ t 2 } \{ t \in R: t_1 \le t \le t_2\} { tR:t1tt2},开区间和半开区间分别略去了集合的两个或一个端点。
我们可以把一个区间 [ t 1 , t 2 ] [t_1,t_2] [t1,t2]表示成一个对象 i i i,其中属性 i . l o w = t 1 i.low = t_1 i.low=t1为低端点,属性 i . h i g h = t 2 i.high=t_2 i.high=t2为高端点,我们称区间 i i i i 1 i^1 i1重叠,如果 i ∩ i 1 ≠ ϕ i \cap i^1\ne \phi ii1=ϕ,即如果 i . l o w ≤ i 1 . h i g h i.low \le i^1.high i.lowi1.high i 1 . l o w ≤ i . h i g h i^1.low \le i.high i1.lowi.high。如下图所示:任何两个区间 i i i i 1 i^1 i1满足区间三分律,即下面三条性质之一成立:

a. i i i i 1 i^1 i1重叠
b. i i i i 1 i^1 i1的左边( i . h i g h < i 1 . l o w i.high<i^1.low i.high<i1.low)
c. i i i i 1 i^1 i1的右边( i 1 . h i g h t < i . l o w i^1.hight<i.low i1.hight<i.low)

在这里插入图片描述
区间树是一种对动态集合进行维护的红黑树,其中每个元素 x x x都包含一个区间 x . i n t x.int x.int,下图说明了区间树是如何表达一个区间集合的。
在这里插入图片描述
一棵区间树,(a)10个区间的集合,它们按左端点自底向上顺序出,(b)表示它们的区间树,每个节点 x x x包含一个区间,显示在虚线的上方,一个以 x x x为根的子树中所包含的区间端点的最大值,显示在虚线的下方。

  • 步骤1:基础数据结构
    选择一棵红黑树,其每个节点 x x x包含一个区间属性 x . i n t x.int x.int,且 x x x的关键字为区间的低端点 x . i n t . l o w x.int.low x.int.low

  • 步骤2:附加信息
    每个节点 x x x中除了自身区间信息之外,还包含一个值 x . m a x x.max x.max,它是以 x x x为根的子树中所有区间的端点的最大值

  • 步骤3:对信息的维护
    n n n个节点的区间树上的插入和删除操作能否在 O ( l g n ) O(lgn) O(lgn)时间内完成。通过给定区间 x . i n t x.int x.int和节点 x x x的子节点的 m a x max max值,可以确定 x . m a x x.max x.max值: x . m a x = m a x ( x . i n t . h i g h , x . l e f t . m a x , x . r i g h t . m a x ) x.max = max(x.int.high, x.left.max, x.right.max) x.max=max(x.int.high,x.left.max,x.right.max)
    更新 m a x max max属性只需要 O ( 1 ) O(1) O(1)的时间,所以插入和删除操作运行时间保持为 O ( l g n ) O(lgn) O(lgn)

  • 步骤4:设计新的操作
    我们需要设计一个新的操作 interval_search(T, i),它是用来找出树T中与区间 i i i重叠的那个节点。
    如下为实现函数:

def interval_search(T, i):
	x = T.root
	# i does not overlap x.int
	while x!=T.nil and not (i.low<=x.high and x.low<=i.high):
		if x.left!=T.nil and x.left.max>=i.low:
			x = x.left
		else:
			x = x.right
	return x

猜你喜欢

转载自blog.csdn.net/BGoodHabit/article/details/105944077