区间二进制搜索树中的所有交叉点

时间:2017-03-10 18:33:05

标签: javascript algorithm binary-search-tree

所以我试图实现一个算法来遍历区间搜索树并找到所有的交叉点。我能够毫无问题地创建和插入节点,但我必须遍历树的算法目前只搜索与查询间隔相交的任何一个间隔。作为示例,如果将(21,23)作为查询参数传递,则树将找到节点16,22作为交集,但忽略当前在根节点右侧的节点。关于如何使算法找到查询与????

相交的EACH节点的任何想法

https://gist.github.com/anonymous/ce4e40e9d9e4af27d66690dcc16245a3

检查所有交叉点的更新版本

我决定在检查交集的算法中找到节点,直到它返回null。

https://gist.github.com/DandroidDeveloper/009717551e3785cde48a53ffdeded7d1

function checkIntersection(interval, tree){
var currentNode = tree.root;
var intersection = {};
while(currentNode){

    console.log("Searching...", currentNode);
    if (currentNode.list.length > 0){
        for (var i = 0; i < currentNode.list.length; i++){
            if (interval[0] < currentNode.list[i].interval[1] && currentNode.list[i].interval[0] < interval[1]){
                intersection.interval = currentNode.list[i].interval;
                intersection.id = currentNode.list[i].id;
                tree.remove(currentNode.list[i].interval, currentNode.list[i].id);
                return intersection;
            }
        }
    }
    if (interval[0] < currentNode.interval[1] && currentNode.interval[0] < interval[1]){
        console.log("INTERSECTION: "+interval, currentNode.interval);
        intersection.interval = currentNode.interval;
        intersection.id = currentNode.id;
        tree.remove(currentNode.interval, currentNode.id);
        return intersection;
    }
    if (!currentNode.left){
        console.log("NO NODE TO LEFT, GO RIGHT");
        if (!currentNode.right){
            console.log("NO MORE NODES");
            return null;
        }
        console.log(currentNode.right);
        currentNode = currentNode.right;
    }
    else if (currentNode.left.max < interval[0]){
        console.log("LEFT MAX: "+currentNode.left.max+" < "+interval[0]+" GO RIGHT");
        currentNode = currentNode.right;
    }
    else{
        console.log("INTERVAL MAY BE TO LEFT, GO LEFT");
        currentNode = currentNode.left;
    }
}
}

function checkAllIntersections(interval, tree){
var intersections = [];
var flag = true;
while(flag){
    var temp = checkIntersection(interval, tree);
    if (!temp){
        flag = false;
    }
    else{
        intersections.push(temp);
    }
}
for (var i = 0; i < intersections.length; i++){
    tree.add(intersections[i].interval, intersections[i].id);
}
return intersections;

}

1 个答案:

答案 0 :(得分:0)

您需要做的就是在遍历树时构造一个对象数组,并在最后返回该数组,而不是仅返回您拥有的第一个查找。以下是您的代码改变了:

function checkIntersection(interval, tree){
var currentNode = tree.root;
var intersection = {};
var intersections = []; //array to return multiple objects
while(currentNode){

    console.log("Searching...", currentNode);
    if (currentNode.list.length > 0){
        for (var i = 0; i < currentNode.list.length; i++){
            if (interval[0] < currentNode.list[i].interval[1] && currentNode.list[i].interval[0] < interval[1]){
                intersection.interval = currentNode.list[i].interval;
                intersection.id = currentNode.list[i].id;
                //---DELETE---tree.remove(currentNode.list[i].interval, currentNode.list[i].id); no need to remove
                intersections.push(intersection); //add the newly found intersection to the returned array
                intersection = {}; //prepare the variable for next find
            }
        }
    }
    if (interval[0] < currentNode.interval[1] && currentNode.interval[0] < interval[1]){
        console.log("INTERSECTION: "+interval, currentNode.interval);
        intersection.interval = currentNode.interval;
        intersection.id = currentNode.id;
        //again no need to remove
        intersections.push(intersection);
        intersection = {};
    }
    if (!currentNode.left){
        console.log("NO NODE TO LEFT, GO RIGHT");
        if (!currentNode.right){
            console.log("NO MORE NODES");
            return intersections;
        }
        console.log(currentNode.right);
        currentNode = currentNode.right;
    }
    else if (currentNode.left.max < interval[0]){
        console.log("LEFT MAX: "+currentNode.left.max+" < "+interval[0]+" GO RIGHT");
        currentNode = currentNode.right;
    }
    else{
        console.log("INTERVAL MAY BE TO LEFT, GO LEFT");
        currentNode = currentNode.left;
    }
}

请注意,即使交叉点仅位于树的最左边的叶子中,此代码也会遍历每个搜索的整个树。要更改它,您可以在最后添加检查(类似于您现在没有进入具有过低最大值的子树的检查),以避免进入查询间隔的过高最小值的子树:

if (interval[1] < currentNode.right.value){ //no intersections possible in the right subtree
    return intersections;
} else {
    currentNode = currentNode.right;
}

只需在现有的任何地方使用此代码段:currentNode = currentNode.right;