簡體   English   中英

間隔二分搜索樹中的所有交集

[英]All intersections in Interval Binary Search Tree

因此,我正在嘗試實現一種算法,以遍歷區間搜索樹並找到所有交叉點。 我能夠毫無問題地創建和插入節點,但是我必須遍歷樹的算法目前僅搜索與查詢間隔相交的任何一個間隔。 例如,如果將(21,23)作為查詢參數傳遞,則樹將找到節點16、22作為交點,但忽略當前位於根節點右側的節點。 關於如何使算法找到與查詢相交的每個節點的任何想法?

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

更新版本檢查所有路口

我決定在檢查交叉點的算法中找到節點時將其刪除,直到返回空值。

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;

}

您需要做的就是在遍歷樹時構造一個對象數組,並在最后返回該數組,而不是僅返回您擁有的第一個查找對象。 這是您的代碼以這種方式更改的:

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM