所以我试图实现一个算法来遍历区间搜索树并找到所有的交叉点。我能够毫无问题地创建和插入节点,但我必须遍历树的算法目前只搜索与查询间隔相交的任何一个间隔。作为示例,如果将(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;
}
答案 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;