Skip to content

广度优先搜索

Breadth-first search · BFS

按无权距离分层访问可达顶点的图遍历算法。

条目类型
算法

形式陈述

给定有限 G=(V,E) 与源点 s,广度优先搜索(BFS)按从 s 出发所需的最少边数遍历可达顶点。有向图版本只扫描出边;无向图版本扫描每条边的两个邻接表记录。算法置 d[s]=0,其余距离为 +,并把 s 标记为已发现后放入先进先出队列。每次取出队首 u,依次检查它的邻接点 v;只有当 v 尚未发现时才执行

d[v]=d[u]+1,π[v]=u,

然后立即标记并入队。记 δ(s,v) 为从 sv 的最少边数,不可达时为 +。算法结束后

d[v]=δ(s,v)

对所有 v 成立;有限距离顶点的父边 (π[v],v) 构成 BFS 树,树上路径给出一条边数最少的路。

证明依赖队列单调性:队中顶点的 d 值始终非降,而且队首与队尾至多相差 1。归纳地看,取出第 k 层顶点时,只可能发现第 k+1 层;因此任何距离小于 k+1 的候选都已更早进入队列。一个顶点首次由 u 发现时,已得到长度 d[u]+1 的路;若另有更短路,其倒数第二个顶点会处在更浅层并更早发现它,矛盾。

n=|V|m=|E|。在邻接表表示和单位成本 RAM 下,每个顶点至多入队、出队一次,有向弧扫描一次,无向边的两个记录各扫描一次,故时间为 Θ(n+m)、辅助空间为 O(n)。邻接矩阵必须为每个出队顶点扫描整行,最坏时间为 Θ(n2);这里的复杂度不含读取顶点标签或生成隐式邻居的额外成本。

直觉

队列保存的是尚未展开的波前。第 k 层全部排在第 k+1 层之前,所以一次“首次发现”同时完成两件事:确认可达,并锁定最少边数。父指针只是从可能的多条最短路中选择一条;距离不随邻接次序改变,具体搜索树却会改变。

BFS 的分层 FIFO 波前

这一点也刻画了 BFS 与深度优先搜索的分工。DFS 的栈优先完成当前分支,适合暴露祖先与退出顺序;BFS 的 FIFO 次序保留距离层。把队列机械换成栈,仍能遍历可达集合,却失去“首次发现即最短”的结论。

例子与边界

设无向图的边为

sa, sb, ac, bc, cd.

s 出发的各层依次是 {s}{a,b}{c}{d},所以 d[c]=2d[d]=3。若 a 先于 b 出队,可能记录 π[c]=a;反过来则可能记录 π[c]=b。两棵 BFS 树不同,但 c,d 的距离相同。另一个孤立顶点 x 从未入队,保持 d[x]=+。若要遍历整张非连通图,可从每个尚未发现的顶点重新启动,得到 BFS 森林;此时不同树根之间没有由本次搜索定义的有限距离。

边权破坏按边数分层。若 sa 的权为 10,而 sbba 的权均为 1,BFS 会偏好一条边的直达路,权重最短路却是成本 2 的绕行。一般非负权应使用Dijkstra 算法;权只取 01 时,0–1 BFS 用双端队列把零权改进放在队首、一权改进放在队尾。

发现标记必须在入队时写入。若拖到出队才标记,菱形图中的共同后继会被多个前驱重复放入队列;在稠密分层图上,重复项可远超 O(n)。平行边不改变最少边数,但应共享同一个“已发现”状态;自环也不能触发重新入队。

推论与应用

BFS 是单位权最短路的标准算法,也能按距离奇偶给二分图二染色、枚举连通分量。Edmonds–Karp 用它选择残量边数最少的增广路,Dinic 算法则用 BFS 构造残量层次图;后两者的“距离”是当前残量网络中的弧数,会随增广而变化。

在有限状态系统中,显式状态模型检查可用 BFS 按反例长度枚举可达配置;一旦命中坏状态,父指针给出一条最短转移数的反例轨迹。这里“最短”只相对于所选状态编码与一步转移,BFS 是搜索算法,状态语义与要检查的性质仍须另行定义。

若图由状态转移规则隐式给出,n,m 应理解为实际生成并访问的状态与转移数;邻居生成、哈希去重和状态编码可能主导成本。外存模型还按块传输计费,不能把 RAM 中的逐边扫描数直接当作 I/O 次数。一般的割或谱稀疏化也不保证逐对无权距离不变,除非所用稀疏器明确承诺保距。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Ch. 20。
  • Jon Kleinberg and Éva Tardos, Algorithm Design, Pearson, 2005,§§3.2–3.3。
关系图谱11 个相邻概念 · 4 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系