找到区间树中的所有交叉点(基于红黑)的复杂性是多少?

时间:2018-06-04 07:14:52

标签: algorithm

所以Stackoverflow有很多关于区间树的问题,但我没有发现任何关于操作findall(Itv)的复杂性,也就是说,给定一个区间Itv,找到所有与{相交的区间{1}},基于红黑的增强间隔树。

我从Robert Sedgewick的课程算法中学到了这个操作可以在Itv中完成,其中O(RlgN)是交叉区间的数量,R是节点数。但是我不确定哪种算法对应于这种复杂性(我谷歌的大多数东西只提到如何知道N是否与任何间隔相交)。我确实在wiki 中找到了Itv操作(章节Java示例:在树中搜索一个点或一个区间),我唯一的问题是,我不知道它是否是{{1我无法证明这一点
无论如何,如果有人能够在bbst增强区间树(非中心区间树)中找到findall(Itv)的有效方法,或者证明维基算法是O(RlgN),或者指向任何相关文献,我会真的很感激。

1 个答案:

答案 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是该子树的高度。子树。由于search1search1的调用是针对不相交的子树(因此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。