UNPKG

1.1 kBJavaScriptView Raw
1/**
2 * Visitor function called on each node
3 * @callback visitor
4 * @param {{}} node The node being visited, it is augmented with the path (an
5 * array of nodes, that leads to it)
6 */
7
8/**
9 * Graph visitor based on the the https://en.wikipedia.org/wiki/Breadth-first_search
10 *
11 * @param {{}} startNode The node where the search/traverse starts
12 * @param {Array} graph The graph to be traversed
13 * @callback {visitor} fn A function called on each node
14 */
15module.exports = function bfs(startNode, graph, fn) {
16 visit([{ node: startNode, path: [] }], graph, fn);
17};
18
19function visit(frontier, graph, fn) {
20 var level = 0;
21 var levels = {};
22
23 while (0 < frontier.length) {
24 var next = [];
25 for (var i = 0; i < frontier.length; i++) {
26 var cur = frontier[i];
27 var node = cur.node;
28 if (fn(cur) === false) {
29 return;
30 }
31 levels[node] = level;
32 for (var adj in graph[node]) {
33 if (typeof levels[adj] === "undefined") {
34 next.push({ node: adj, path: cur.path.concat(node) });
35 }
36 }
37 }
38 frontier = next; // eslint-disable-line no-param-reassign
39 level += 1;
40 }
41}