BFS(广度优先搜索)
是一种用于遍历或搜索树/图的算法,逐层访问节点,适合解决最短路径、层级遍历等问题。
一、BFS 的核心思想
队列结构 :用队列(先进先出)保存待处理的节点。
逐层扩散 :从起点开始,先处理当前层的所有节点,再处理下一层。
避免重复:用 visited 集合(或标记)记录已访问的节点,防止死循环。
二、代码框架
javascript
function BFS(start, target) {
const queue = [start]; // 初始化队列
const visited = new Set(); // 记录已访问的节点
visited.add(start);
let step = 0; // 记录扩散的步数(可选)
while (queue.length > 0) {
// 处理当前层的所有节点
const levelSize = queue.length;
for (let i = 0; i < levelSize; i++) {
const current = queue.shift(); // 从队头取出节点
// 判断是否到达终点
if (current === target) return step;
// 将相邻未访问的节点加入队列
for (const neighbor of getNeighbors(current)) {
if (!visited.has(neighbor)) {
queue.push(neighbor);
visited.add(neighbor);
}
}
}
step++; // 步数增加(视题目需求决定)
}
return -1; // 未找到路径
}
三、经典问题示例
1、二叉树层序遍历
javascript
function levelOrder(root) {
if (!root) return [];
const queue = [root];
const result = [];
while (queue.length > 0) {
const levelSize = queue.length;
const currentLevel = [];
for (let i = 0; i < levelSize; i++) {
const node = queue.shift();
currentLevel.push(node.val);
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
result.push(currentLevel);
}
return result;
}
2、 迷宫最短路径
假设有一个二维网格,求从起点 (0,0) 到终点 (m-1, n-1) 的最短步数(1 表示障碍):
javascript
function shortestPath(grid) {
const rows = grid.length, cols = grid[0].length;
const queue = [[0, 0]]; // 起点
const visited = new Set().add('0,0');
let step = 0;
const directions = [[1,0], [-1,0], [0,1], [0,-1]]; // 上下左右
while (queue.length > 0) {
const levelSize = queue.length;
for (let i = 0; i < levelSize; i++) {
const [x, y] = queue.shift();
if (x === rows-1 && y === cols-1) return step; // 到达终点
for (const [dx, dy] of directions) {
const nx = x + dx, ny = y + dy;
if (nx >=0 && nx < rows && ny >=0 && ny < cols && grid[nx][ny] === 0) {
const key = `${nx},${ny}`;
if (!visited.has(key)) {
queue.push([nx, ny]);
visited.add(key);
}
}
}
}
step++;
}
return -1; // 无法到达
}
四、BFS 的适用场景
1、最短路径问题(无权图最短步数)
2、层级遍历(如二叉树层序遍历)
3、扩散类问题(如病毒传播模拟、社交网络层级关系)
五、注意事项
1、队列操作 :JavaScript 中直接用数组的 shift() 效率较低,可优化为维护一个指针(类似双端队列)。
2、去重方式 :根据问题场景,可以用 Set、哈希表或直接修改原数据(如标记为已访问)。
3、终止条件:根据问题提前判断是否到达目标。