前言
广度优先遍历,沿图(树)宽度进行遍历,可采用邻接矩阵和邻接表作为存储结构,分别为O(n**2),O(n+e)。时间效率有所不同
一、模板
let BFS = function(...){
const edges = new Array(n).fill(0).map(() => new Array());
//建立邻接表
for(const i of arr){
edges[i[0]].push(i[1]);
}
//初始化邻接表
let visited = new Set();
//访问状态
let queue = [source];
//根节点放入队列
while(queue.length > 0){
let dot = queue.shift();
//访问并删除该节点
for(const i of edges[dot]){
if(!visited.has(i))
visited.add(i);
queue.push(i);
}
//未访问且合法
}
}
return; //queue为空,结束遍历
}
二、例题
1.Leetcode 1971. 寻找图中是否存在路径
var validPath = function(n, edges, source, destination) {
let path = new Array(n).fill(0);
for(let i = 0; i < n; i++){
path[i] = new Array();
}
for(let i of edges){
path[i[0]].push(i[1]);
path[i[1]].push(i[0]);
}
//初始化邻接表
const visited = new Set();
//记录访问节点
let stack = [source];
while (stack.length > 0) {
let dot = stack.shift();
if(dot == destination)return true;
for(let i = 0; i < path[dot].length; i++){
if(!visited.has(path[dot][i])){
visited.add(path[dot][i]);
stack.push(path[dot][i]);
}
}
}
return false;
};
2.LeetCode LCP 07. 传递信息
var numWays = function(n, relation, k) {
let ans = 0;
let path = new Array(n).fill(0).map(() => Array());
for(let i of relation){
path[i[0]].push(i[1]);
}
let queue = [0];
let res = 0;
while (queue.length > 0 && ans < k) {
let len = queue.length;
for(let i = 0; i < len; i++){
let dot = queue.shift();
for(let i of path[dot]){
queue.push(i);
}
}
ans++;
}
while(queue.length > 0){
if(queue.shift() == n-1)res++;
}
return res;
};
总结
图的基础遍历方法,根据题目不同增添即可