所以Stackoverflow有很多关于区间树的问题,但我没有发现任何关于操作findall(Itv)
的复杂性,也就是说,给定一个区间Itv
,找到所有与{相交的区间{1}},基于红黑的增强间隔树。
我从Robert Sedgewick的课程算法中学到了这个操作可以在Itv
中完成,其中O(RlgN)
是交叉区间的数量,R
是节点数。但是我不确定哪种算法对应于这种复杂性(我谷歌的大多数东西只提到如何知道N
是否与任何间隔相交)。我确实在wiki 中找到了Itv
操作(章节Java示例:在树中搜索一个点或一个区间),我唯一的问题是,我不知道它是否是{{1我无法证明这一点
无论如何,如果有人能够在bbst增强区间树(非中心区间树)中找到findall(Itv)
的有效方法,或者证明维基算法是O(RlgN)
,或者指向任何相关文献,我会真的很感激。
答案 0 :(得分:2)
是的,Wiki算法(由CLRS引用)是O(R log N)。由于单一过程实现和检查的放置,分析有点棘手,所以让我展示和分析一个密切相关的版本(可以通过在父和子调用之间移动一些测试并替换{{1与search1
):
search
除了对class Node {
// Binary search tree sorted on start.
// The interval at this node is [start, end).
// maxEnd is the maximum value of end in this tree.
int start, end, maxEnd;
Node left, right;
void search(int p, Collection<Node> results) {
if (p < start) {
if (left != null && p < left.maxEnd) left.search(p, results);
} else {
// p >= start
if (left != null && p < left.maxEnd) left.search1(p, results);
if (p < end) results.add(this);
if (right != null && p < right.maxEnd) right.search(p, results);
}
}
void search1(int p, Collection<Node> results) {
// Precondition:
// p < maxEnd
// for every node x in this tree, p >= x.start
if (left != null && p < left.maxEnd) left.search1(p, results)
if (p < end) results.add(this);
if (right != null && p < right.maxEnd) right.search1(p, results);
}
}
的调用外,方法search1
在二叉搜索树中是正常下降。不包括这些调用的成本是O(log N),因为树高是O(log N)。
我拆分search
的原因是,对于调用search1
的每个节点,至少有一个后代被添加到结果中(即节点search1
x
)。我声称存在一个常数c,使得对于所有可能的调用,x.end == this.maxEnd
的运行时间受c R'H限制,其中R'是子树中的结果数,H是该子树的高度。子树。由于search1
对search1
的调用是针对不相交的子树(因此R'值的总和以R为界),而H是O(log N),因此总运行时间为O(R记录N)。
通过归纳证明了这一主张。令RL为左子树中的结果数,RR为右子树中的结果数。运行时间重复是
search
其中选择c + c RL (H - 1) + c RR (H - 1) ≤ c + c R' (H - 1) ≤ c R' H,
^^^^^^^^^^^^ ^^^^^^^^^^^^
left call right call
来涵盖c
中完成的非递归工作,因为R'≥1。我们可以假设R'≥1是分割search1
的原因首先;直接在search1
上证明c(R'+ 1)H的界限是行不通的,因为两个递归调用都需要+1。