如何停止广度优先搜索递归函数

时间:2017-09-09 13:15:25

标签: javascript algorithm search

我想在到达指定的单元格后停止我的广度优先搜索功能。

现在我在到达指定的单元格后显示警告,但仍然访问其余节点。您可以看到此行为here(请选择广度优先搜索)。

function drawBreadthFirstSearch(current, start, last, queue, animation_speed) {
    setTimeout(function () {
        if (queue.length >= 0) {
            current = queue.shift();

            if (current !== last) {
                current.color = "#c6e0b4";
                current.changeColor();
            } else {
                alert('The end!')
                return
            }

            var childs = checkNeigbors(current.i, current.j)
            if (childs) {
                childs.forEach(function (child) {
                    if (child.visited === false) {
                        child.color = "green";
                        child.changeColor();

                        queue.push(child)
                        child.visited = true;
                        drawBreadthFirstSearch(current, start, last, queue, animation_speed)
                    }
                });
            }
        }
    }, animation_speed);
}

函数checkNeigbors返回单元格数组。

forEach更改为for无效。

2 个答案:

答案 0 :(得分:2)

它继续的原因是forEach循环将启动几个递归调用,它们都启动一个计时器。因此,随着搜索树的宽度增加,待处理计时器的数量也会增加。结束一个计时器的回调不会阻止其他待处理的计时器执行回调。

一个快速解决方法是在找到匹配项后立即将队列清空。由于计时器回调仅在队列不为空时执行某些操作,队列引用在所有函数调用中共享,因此可以避免任何进一步的搜索。

        queue.length = 0; // <--- add this.
        alert('The end!')
        return

答案 1 :(得分:0)

在到达已经搜索过的单元格后停止对后代和兄弟姐妹的迭代,你应该在三个地方使用返回值:

首先,当到达所需的单元格时,您应该通知递归实例,即搜索已经结束:

        } else {
            alert('The end!');
            return false;
        }

第二个返回命令应该在forEach循环中,以便在我们找到所请求的单元格时停止迭代节点的子节点:

                      if (!drawBreadthFirstSearch(current, start, last, queue, animation_speed)) return false;

第三个返回命令应该在最后一个函数的行上,它代表:仍然没有找到单元格,继续搜索:

        }, animation_speed);
        return true;
   }