交互式图论学习
交互式图论学习
Guest User
Using app without sign in
交互式广度优先搜索可视化工具
逐层探索图,在深入之前访问所有邻居
选择算法并生成步骤以开始可视化
广度优先搜索(BFS)是一种基础的图遍历算法,按层逐级探索图。从源节点出发,它先访问距离为一的所有邻居,再访问距离为二的所有节点,依此类推,并用队列维护搜索前沿。由于总是先扩展最近的未访问节点,BFS 能在任何无权图中找到最短路径。
BFS 先把起始节点放入队列并标记为已访问,然后反复取出队首节点,检查其邻居,把每个尚未访问的邻居追加到队尾。这种先进先出的机制保证节点按到源点的距离递增顺序被处理。算法运行时间为 O(V + E),空间为 O(V),其中 V 是节点数,E 是边数。
BFS 支撑无权网络中的最短路径查询、网络爬虫、社交网络好友推荐、GPS 广播搜索以及树的层序遍历。它也是 Edmonds-Karp 最大流等高级算法的基础。BFS 是编程面试中最常考的题目之一,常出现在网格、迷宫和单词接龙类问题中。
整个算法就是一个队列加一个已访问集合。BFS 之所以出名的其他性质,全都源自队列交还结点的顺序。
BFS(图, 源点):
已访问 = {源点}
dist[源点] = 0
队列 = [源点]
当队列非空时:
u = 队列.取出队首()
对 u 的每个邻居 v:
若 v 不在已访问中:
已访问.加入(v)
dist[v] = dist[u] + 1
父结点[v] = u
队列.加入队尾(v)不变式是:队列中始终只包含至多两个相邻距离层的结点,且按距离非递减排列。正是这一条性质保证了 dist 的正确性:结点在第一次被看到时就确定了距离,此后不可能以更小的代价被抵达。
从 A 出发在可视化工具默认加载的图上运行 BFS,可以在上方面板中逐步对照。
示例图: 无向边 A-B (2)、A-C (3)、B-C (1) 和 C-D (4)。BFS 完全忽略权重,只数跳数,因此每条边都算作一。
最终距离为 A 0、B 1、C 1、D 2,父指针给出最短路径树 A 到 B、A 到 C、C 到 D。注意 BFS 经由 C 抵达 D,尽管该路径的加权代价为 7,而 A 到 B 到 C 只需 3:它唯一优化的是跳数,这正是加权图必须改用 Dijkstra 的原因。
时间: O(V + E) · 空间: O(V)
每个结点至多入队一次,因为它在入队时而非出队时就被标记为已访问,这把外层循环限制在 V 次迭代内。循环体内的工作量与当前结点的度成正比,而无向图中所有度之和为 2E,因此扫描邻居总共为 O(E)。空间主要由已访问集合、距离数组和队列决定,各为 O(V)。若改用邻接矩阵,每个结点的邻居扫描变为 O(V),整体退化为 O(V 的平方)。
只要边没有权重,BFS 就是默认选择。一旦出现权重,或目标从距离转向结构,就该换别的算法。
| 替代算法 | 以下情况更合适 | 代价 |
|---|---|---|
| DFS | 你需要的是结构性结论而非距离:环、拓扑序、连通分量、桥。在宽而浅的图上它也更省内存。 | O(V + E) |
| Dijkstra 算法 | 边带非负权重,跳数不再等于距离。 | O((V + E) log V) |
| 0-1 BFS | 所有权重非 0 即 1。用双端队列替代队列,胜过完整的优先队列。 | O(V + E) |
| 双向 BFS | 你要的是大图中某一特定点对之间的距离,并且可以从目标反向搜索。 | O(b^(d/2)) |