JS实现图的BFS和DFS
通过在极客时间上学习的算法内容.
我用JS实现图的BFS和DFS.
这里分享给大家.
本文使用图的存储方式是 邻接表
代码中使用的是无向图, 有向图类似.
例子都是从 s 到 t
最后一部分有全部的代码, 和一个小的测试用例
BFS
BFS 也就是 Breadth First Search
广度优先搜索
可以理解为地毯式地搜索, 一层一层地搜索.
是不是想起树的层序遍历了?
BFS 同样利用了一个 queue 作为辅助工具.
如果, 我们想要向上图一样遍历. 首先我们要解决下面的三个问题
- 访问过的顶点, 不能再访问了
- 要记录到某一顶点前经过的顶点
- 需要一层一层顶点的地遍历
为了解决这三个问题, 我们引入了三个重要的辅助变量
- visited 一个数组, 大小为顶点的个数, 默认都是false , 用于记录顶点是否被访问;
- prev 一个数组, 大小为顶点的个数. 默认值为 -1, 用于记录访问到该顶点的前一个顶点
- queue 队列(js中可以直接使用数组), 用于存储层序遍历时的顶点
层序搜索, 获取到的路径是 最短路径
// 广度优先搜索
// 最短路径
breadth_first_search(s, t) {
const prev = new Array(this.v).fill(-1);
// 用于记录 顶点是否被访问过
const visited = new Array(this.v).fill(false);
// 用于记录 访问到该节点的前一个节点
// 用于遍历顶点, 一层一层地遍历
const queue = [s];
// 循环结束的条件
// 找到t, 或者queue为空
let prev_v = null;
while (queue.length !== 0) {
let cur = queue.shift();
visited[cur] = true;
// 当前顶点的邻接表
let cur_list = this.adj[cur];
let unvisited = cur_list
// 遍历 cur_list中没有被访问过的节点
.filter((node) => {
return !visited[node];
});
for (let index = 0; index < unvisited.length; index++) {
const node = unvisited[index];
// 设置 prev 和 visited
prev[node] = cur;
visited[node] = true;
// 如果有t 结束
if (node === t) {
return prev;
} else {
// 没有 将其放入 queue中,继续循环
queue.push(node);
}
}
}
this.print_path(s, t, prev);
return