Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在不包含查询的间隔树中查找最近的间隔_Algorithm_Tree_Interval Tree - Fatal编程技术网

Algorithm 在不包含查询的间隔树中查找最近的间隔

Algorithm 在不包含查询的间隔树中查找最近的间隔,algorithm,tree,interval-tree,Algorithm,Tree,Interval Tree,我已经在Java中实现了一个CLRS算法(它使用红黑树作为底层结构)。在这本书中(就我在网上看到的),它讨论了如何找到间隔包含被查询编号的节点 在我的例子中,如果被查询的数字不属于任何间隔,我想知道“最近的”节点是什么,即那些间隔在查询之前和之后的节点。我使用以下函数完成了这项工作。每个节点都包含间隔(int-low、int-high)及其子树的最小值和最大值 public Node[] findPrevNext(int query) { if (tree.root.isNull())

我已经在Java中实现了一个CLRS算法(它使用红黑树作为底层结构)。在这本书中(就我在网上看到的),它讨论了如何找到间隔包含被查询编号的节点

在我的例子中,如果被查询的数字不属于任何间隔,我想知道“最近的”节点是什么,即那些间隔在查询之前和之后的节点。我使用以下函数完成了这项工作。每个节点都包含间隔(int-low、int-high)及其子树的最小值和最大值

public Node[] findPrevNext(int query) {
    if (tree.root.isNull())
        return null;
    else {
        Node prev = findPrev(query, tree.root, new Node());
        Node next = findNext(query, tree.root, new Node());
        Node[] result = {prev, next};
        return result;
    }
}

private Node findPrev(int query, Node x, Node prev) {
    if (x.interval.high < query && x.interval.high > prev.interval.high)
        prev = x;
    if (!x.left.isNull())
        prev = findPrev(query, x.left, prev);
    if (!x.right.isNull())
        prev = findPrev(query, x.right, prev);
    return prev;
}

private Node findNext(int query, Node x, Node next) {
    if (x.interval.low > query && x.interval.low < next.interval.low)
        next = x;
    if (!x.left.isNull())
        next = findNext(query, x.left, next);
    if (!x.right.isNull())
        next = findNext(query, x.right, next);
    return next;
}
public节点[]findPrevNext(int查询){
if(tree.root.isNull())
返回null;
否则{
Node prev=findPrev(query,tree.root,new Node());
Node next=findNext(query,tree.root,new Node());
节点[]结果={prev,next};
返回结果;
}
}
私有节点findPrev(int查询、节点x、节点prev){
if(x.interval.highprev.interval.high)
prev=x;
如果(!x.left.isNull())
prev=findPrev(查询,x.left,prev);
如果(!x.right.isNull())
prev=findPrev(查询,x.right,prev);
返回上一个;
}
私有节点findNext(int查询、节点x、节点next){
if(x.interval.low>query&&x.interval.low
当然,问题是函数findPrev()和findNext()都遍历整个树,并且没有利用树的结构。有没有办法在O(lgn)时间内执行此查询

我还考虑了创建第二个包含所有间隔间隔的间隔树的可能性,并简单地在那里执行查询。然后,节点将包含关于在该间隙之前和之后的元素的信息(我已经尝试过了,但到目前为止还没有成功实现)


编辑:请注意,函数findPrevNext()是在尝试查找查询失败后调用的。因此,我们知道查询事先不会落在任何给定的时间间隔内。

Java
TreeMap
,它实现了一个红黑树,实现了一些方法,并且返回的映射部分小于查询点(对于
headMap
)或大于查询点(对于
tailMap
)。如果您为树实现了类似于这些方法的方法,那么这应该允许您从查询点进行线性遍历,以找到N个最近的间隔,而不必遍历整个树。

Java
树映射
,它实现了一个红黑树,实现返回地图部分小于查询点(对于
头部地图
)或大于查询点(对于
尾部地图
)的方法和。如果您为树实现了类似于这些方法的方法,那么这应该允许您从查询点进行线性遍历,以找到N个最近的间隔,而不必遍历整个树。

由于间隔是按低端排序的,因此上面的方法很简单–从间隔所在的孔开始[query,query]将是,提升树,直到您从其左子节点到达父节点;该父节点是所需的节点


下面似乎需要检查max字段。如果子树只包含查询下方的间隔(即,那些较低端点低于查询的间隔),我们可以通过在节点最大值为max的路径上降序来提取最近下方的一个候选。有O(log n)最大化这样的子树,在搜索算法中每次一个,我们考虑向左,但没有。我们还需要检查原始搜索路径上的O(logn)节点。天真地,这个想法导致了一个O(log2n)时间算法,但是如果我们在每个节点上保持一个指向某个间隔的指针,该间隔的高值等于该节点的最大值,那么我们得到一个O(logn)-时间算法。

因为间隔是按低端排序的,所以上面的方法很简单–从间隔[query,query]所在的孔开始,向上爬树,直到从左子节点到达父节点;该父节点是所需的节点

下面似乎需要检查max字段。如果子树只包含查询下方的间隔(即,那些较低端点低于查询的间隔),我们可以通过在节点最大值为max的路径上降序来提取最近下方的一个候选。有O(log n)最大化这样的子树,在搜索算法中每次一个,我们考虑向左,但没有。我们还需要检查原始搜索路径上的O(logn)节点。天真地,这个想法导致了一个O(log2n)时间算法,但是如果我们在每个节点上保持一个指向某个间隔的指针,该间隔的高值等于该节点的最大值,那么我们得到一个O(logn)-时间算法