最近遇到一个版本区间冲检测问题,这个问题描述如下:
给定一个版本区间[x,y],试问他是否与一个版本区间集合中的区间有重叠。在网上收集了一下相关资料,发现一个叫区间树的数据结构,网址 http://www.geeksforgeeks.org/interval-tree/ 对其有一个简单的介绍。
首先在这里简单介绍下区间树:区间树每个节点按区间的左端点(所以区间的左端点不能重复)形成一颗红黑树,每个节点中存储着一个区间[u,v]以及以本节点为根的子树中所有区间的最大右端点m。在区间树上进行区间查找的时间为O(lgn)。区间树如下图所示:
树中每个节点的定义如下:
struct Interval
{
int low , high ;
};
struct ITNode
{
Interval ∗ i ;
int max;
ITNode ∗ left , ∗right ;
};
在区间树root中查找是否有与区间i重叠的区间的算法为:
bool doOVerlap( Interval i1 , Interval i2 )
{
if ( i1 . low <= i2 . high && i2 . low <= i1 . high )
return true ;
return false ;
}
Interval ∗overlapSearch (ITNode ∗root , Interval i )
{
if ( root == NULL) return NULL;
if (doOVerlap(∗( root−>i ) , i ))
return root−>i ;
if ( root−>left != NULL && root−>left −>max >= i . low)
return overlapSearch ( root−>left ,
i );
return overlapSearch ( root−>right ,
i );
}
这个算法的正确性据我所知没有资料提及,而我个人觉得其正确性不是那么明显和直观。所以,我试着自己证明了一下。
我们首先形式化这个问题:有一颗区间树,根节点为{[a,b],m1},根节点的左孩子为{[c,d],m2},右孩子为{[e,f],m3}。
不失一般性,假设用上述算法判断在这颗区间树(图2)中是否有区间与待判断区间[x,y]重叠。在开始证明前,需要说明的是:
下面我们就开始证明