返回算法课程
图与搜索基础

广度优先搜索Breadth-First Search

用队列按距离一层层扩展,先处理离起点更近的节点。

25 分钟前置:队列 · 图的邻接表 · 集合

01先从一个问题出发

在每条路都走一步的迷宫里寻找最少步数。先检查一步可达的位置,再检查两步可达的位置。

一个具体的例子

0 连接 1、2,1 连接 3:BFS 从 0 开始得到层 {0} → {1,2} → {3}。

02最直接的办法,为什么慢?

枚举所有简单路径,再选择最短的。

暴力 · 最坏 O(V!) 条路径

同一节点会通过大量不同路径被重复探索,简单路径数量可能达到阶乘级。

03一步步,推导出优化思路

1

发现可以复用的信息

无权图中,路径长度只由边数决定。

2

建立可维护的状态

用先进先出队列保证距离较小的节点先扩展。

3

消除重复工作

节点第一次被发现就标记并入队,避免环和重复入队。

贯穿算法的不变量

队列中的节点按距源点的最少边数非递减排列。

04让每一步,都看得见

试着先预测下一步,再点击「下一步」验证。变量、动画与代码会同步变化。

Breadth-First Search交互演示
STEP 01 / 18
012345
无向图 · 源点 0 · 邻居按编号处理
当前处理已处理 / 已确定未处理
01

从节点 0 开始:入队时标记,避免重复进入队列。

bfs.py参考实现 · 当前第 4 行
正在载入代码编辑器…

动画展示参考实现的执行轨迹。切换语言时,当前操作会定位到对应代码行。

05复杂度,来自具体的工作量

时间复杂度
O(V+E)O(V+E)

邻接表实现中每个可达节点出队一次,每条无向边最多检查两次,总共 O(V+E)。

辅助空间
O(V)O(V)

visited、队列和输出各最多包含 V 个节点。JavaScript 用 head 下标避免 shift 的线性搬移。

拖动 n,看看增长速度

06看到什么,应该想到它?

这些特征值得停下来想一想:

关键词只是线索,继续检查适用条件

07这些细节,容易踩坑

01

入队时标记

等到出队才标记,会让同一节点重复进入队列。

02

权重限制

边权不同的最短路一般不能直接用普通 BFS。

08把想法带进真实题目

先说出模式和适用条件,再开始写代码。

09不用背模板,回答这几个问题

01什么时候标记 visited?

02BFS 最短路适用于?

03图不连通时,从 0 开始会怎样?

你已经走完了这次推导。

能用自己的话解释复杂度和不变量,再标记为掌握。

把知识连起来