区间树算法,支持不重叠的区间合并
Posted
技术标签:
【中文标题】区间树算法,支持不重叠的区间合并【英文标题】:Interval tree algorithm that supports merging of intervals with no overlap 【发布时间】:2011-02-05 07:57:35 【问题描述】:我正在寻找一种类似于 CLR 中的红黑区间树的区间树算法,但它默认支持区间合并,因此不会有任何重叠区间。
换句话说,如果您有一棵包含两个区间 [2,3] 和 [5,6] 的树,并且添加了区间 [4,4],那么结果将是一棵仅包含一个区间 [2,6] 的树].
谢谢
更新:我正在考虑的用例是计算传递闭包。间隔集用于存储后继集,因为它们一直是found to be quite compact。但是,如果您将区间集表示为链表,我发现在某些情况下它们会变得非常大,因此找到插入点所需的时间也是如此。因此我对区间树感兴趣。此外,可能会有很多将一棵树与另一棵树合并(即一组 OR 操作) - 如果两棵树都很大,那么使用两棵树的中序游走而不是重复插入每个间隔来创建一棵新树可能会更好。
【问题讨论】:
我已经删除了我的答案,因为我愚蠢地忽略了一些案例。它仍然可以修复,但会变得更加复杂。无论如何,由于您更新说您将主要合并整个树,因此答案似乎不再有用,因为按顺序遍历会更快。 哦,好的。有时我会合并两棵大树,而 inorder 可能会更快,但更多时候我会将一棵小树添加到一棵大树中。 【参考方案1】:我看到的问题是插入一个大的间隔会消除树的一大块,从而难以恢复红黑不变量。
我认为使用伸展树会更容易,如下所示。为简单起见,每棵树都包含两个哨兵,一个区间 A
在所有其他区间的左侧,一个区间 Z
在右侧。在插入区间I
时,将I
的前身H
展开到树的根部。树的样子
H
/ \
... X
/ \
... ...
现在分离 X
并将 I
的后继者 J
展开到根目录。
H J
/ / \
... ... ...
此时所有与I
重叠的区间都在J
的左子树中。分离该子树并将其所有节点放在空闲列表中,必要时扩展I
。将I
设为H
和J
的父级
I
/ \
H J
/ \
... ...
继续我们的快乐之路。这个操作是 O(log n) 摊销的,其中 n 是树节点的数量(这可以通过检查 splay 树势函数和做很多代数来证明)。
我应该补充一点,通过插入一棵树的根然后合并左右子树,可以实现自然递归的树到树合并。不知道怎么分析。
【讨论】:
以上是关于区间树算法,支持不重叠的区间合并的主要内容,如果未能解决你的问题,请参考以下文章
2021-09-28:合并区间。以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠