BFS(广度优先搜索)算法详解:原理、实现与应用

发布时间:2026/7/25 3:24:05
BFS(广度优先搜索)算法详解:原理、实现与应用 1. 什么是 BFS广度优先搜索Breadth-First SearchBFS是一种用于遍历或搜索树或图的算法。它从根节点或任意节点开始逐层地访问所有相邻节点然后再进入下一层。BFS 的核心思想是“先访问离起点最近的节点”因此它天然适合解决最短路径问题在无权图中。2. BFS 的核心思想与特点队列Queue驱动BFS 使用队列来存储待访问的节点遵循先进先出FIFO原则。逐层遍历从起点开始先访问所有距离为 1 的节点再访问距离为 2 的节点依此类推。避免重复访问通常需要一个 visited 集合或数组来标记已访问的节点防止陷入循环。无权图最短路径在边权均为 1 的图中BFS 首次访问到目标节点时经过的路径就是最短路径。3. BFS 算法步骤伪代码def bfs(graph, start): visited set() # 记录已访问节点 queue deque([start]) # 使用双端队列作为队列 visited.add(start) while queue: node queue.popleft() print(node) # 处理当前节点 for neighbor in graph[node]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor)4. BFS 的典型应用场景图的连通性判断判断两个节点是否连通。无权图最短路径如迷宫最短路径、单词接龙最短转换序列。层次遍历二叉树的层序遍历、多叉树的层序输出。扩散问题如岛屿数量、腐烂的橘子、广播消息传播范围。状态搜索八数码问题、华容道等状态空间搜索。5. BFS 与 DFS 的对比特性BFS广度优先搜索DFS深度优先搜索数据结构队列Queue栈Stack或递归遍历顺序逐层遍历一条路走到黑再回溯空间复杂度O(最宽层的节点数)O(最大深度)适用问题最短路径、扩散问题拓扑排序、连通分量、回溯实现复杂度通常需要显式队列递归写法更简洁6. 实战示例二叉树的层序遍历Javapublic ListListInteger levelOrder(TreeNode root) { ListListInteger result new ArrayList(); if (root null) return result; QueueTreeNode queue new LinkedList(); queue.offer(root); while (!queue.isEmpty()) { int levelSize queue.size(); ListInteger level new ArrayList(); for (int i 0; i levelSize; i) { TreeNode node queue.poll(); level.add(node.val); if (node.left ! null) queue.offer(node.left); if (node.right ! null) queue.offer(node.right); } result.add(level); } return result; }7. BFS 的优化与变体双向 BFS从起点和终点同时开始搜索相遇时即找到最短路径大幅减少搜索空间。多源 BFS初始时将多个源点同时加入队列用于解决多个起点的扩散问题如多个腐烂橘子同时扩散。A* 搜索在 BFS 基础上加入启发式函数优先搜索最有希望的节点用于带权图的最短路径。0-1 BFS使用双端队列边权为 0 的插入队首边权为 1 的插入队尾解决边权只有 0 和 1 的图的最短路径。8. 常见误区与注意事项忘记标记 visited会导致重复访问甚至无限循环。队列与层次遍历需要记录当前层大小时应在进入循环前获取 queue.size()。空间复杂度BFS 在最坏情况下需要存储整层的节点对于分支因子大的图可能内存消耗较大。无权图假设BFS 只能直接用于无权图的最短路径带权图需要使用 Dijkstra 等算法。9. 总结BFS 是一种基础且强大的图遍历算法其逐层遍历的特性使其成为解决最短路径、扩散、层次遍历等问题的首选。掌握 BFS 的核心实现队列 visited 标记以及其典型应用场景是算法学习中的重要一环。在实际编码中注意边界条件处理、避免重复访问并可根据问题特点选择双向 BFS、多源 BFS 等优化变体。