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无向图 · 源点 0 · 邻居按编号处理
当前处理已处理 / 已确定未处理
01
从节点 0 开始:入队时标记,避免重复进入队列。
bfs.py参考实现 · 当前第 4 行
正在载入代码编辑器…
动画展示参考实现的执行轨迹。切换语言时,当前操作会定位到对应代码行。
05复杂度,来自具体的工作量
时间复杂度
邻接表实现中每个可达节点出队一次,每条无向边最多检查两次,总共 O(V+E)。
辅助空间
visited、队列和输出各最多包含 V 个节点。JavaScript 用 head 下标避免 shift 的线性搬移。
06看到什么,应该想到它?
关键词只是线索,继续检查适用条件07这些细节,容易踩坑
01
入队时标记
等到出队才标记,会让同一节点重复进入队列。
02
权重限制
边权不同的最短路一般不能直接用普通 BFS。
08把想法带进真实题目
先说出模式和适用条件,再开始写代码。
09不用背模板,回答这几个问题
01什么时候标记 visited?
02BFS 最短路适用于?
03图不连通时,从 0 开始会怎样?
你已经走完了这次推导。
能用自己的话解释复杂度和不变量,再标记为掌握。