图的遍历

1385 字
7 分钟
图的遍历
Warning

含AI生成内容

图的遍历#

图的遍历需要解决两个特殊问题:一是图中可能存在回路,需要标记已访问顶点防止重复访问;二是图可能不连通,需要遍历所有顶点,对每个未访问顶点启动一次遍历。

BFS(广度优先搜索)#

核心思想#

BFS 的核心是逐层扩展——从起始顶点出发,先访问其所有邻接顶点,再访问邻接顶点的邻接顶点,依此类推。过程类似于水波扩散。

  • 数据结构:队列(FIFO),保证层次顺序
  • visited 数组:标记已访问顶点,防止重复入队
  • 每层距离相同:第 k 层的顶点距离源点恰好为 k

算法过程#

层次 0: v0
层次 1: v1 v2 v3 (v0 的邻接顶点)
层次 2: v4 v5 (v1,v2,v3 的未访问邻接顶点)
  1. 访问起始顶点 v,标记 visited[v] = true,v 入队
  2. 队列非空时循环:队头 u 出队,检查 u 的所有邻接顶点 w,若 w 未访问则标记并入队
  3. 队列为空时,从 v 出发可达的所有顶点均已访问

对于非连通图,需遍历所有顶点,对未访问的顶点再次调用 BFS(调用次数 = 连通分量个数)。

BFS 求无权图最短路径#

BFS 的一个关键应用是求无权图(边权均为 1)的单源最短路径。由于逐层扩展的特性,某顶点首次被访问时的距离一定是最短距离

维护两个数组:

  • d[v]:源点到 v 的最短距离(初始化为 -1 表示未访问)
  • path[v]:v 的前驱顶点,用于回溯还原路径

路径还原:从目标顶点 t 沿 path[] 回溯到源点,逆序即为最短路径。

易错:BFS 求最短路径仅适用于无权图。如果边有不同的权值,BFS 的”最少边数”不等于”最小权值和”,此时必须使用 Dijkstra 算法。

BFS 生成树#

对连通图从 v 进行 BFS 时,所有引起顶点首次被访问的边构成一棵BFS 生成树。树中从根到任意顶点的路径即为原图中从 v 到该顶点的最短路径(边数最少)。非连通图对应BFS 生成森林


DFS(深度优先搜索)#

核心思想#

DFS 的核心策略是尽可能深地搜索图的分支,走到死胡同时再回溯

  • 数据结构:栈(递归调用栈自动完成回溯)
  • visited 数组:标记已访问顶点
  • 回溯:当前顶点的所有邻接点都已访问时,沿原路退回上一顶点

算法过程#

  1. 从起始顶点 v 出发,标记 v 为已访问
  2. 依次检查 v 的所有邻接点 w:
    • 若 w 未被访问,递归地对 w 执行 DFS
    • 若 w 已被访问,跳过
  3. 当 v 的所有邻接点都已被访问,回溯到上一层

非连通图DFSTraverse 中调用 DFS 的次数 = 连通分量个数。

DFS 生成树#

对连通图进行 DFS,所有经过的边(递归调用时使用的边)构成一棵DFS 生成树。非连通图产生DFS 生成森林

DFS 检测有向图环(三色标记法)#

DFS 可以用三种状态标记顶点来检测有向图是否有环:

  • 0(未访问):尚未遍历到
  • 1(访问中):在当前递归栈上
  • 2(已完成):该顶点的所有后继已遍历完毕

若 DFS 过程中遇到状态为 1 的顶点(即遇到了一条回边),则说明存在环。


BFS vs DFS 对比#

对比项BFSDFS
数据结构队列栈(递归调用栈)
思想逐层扩展尽可能深入,回溯
时间复杂度(邻接表)O(V+E)O(V+E)
时间复杂度(邻接矩阵)O(V2)O(V2)
空间复杂度O(V)O(V)
最短路径可求无权图最短路径不能
适用场景最短路径、层次遍历连通性、路径搜索、拓扑排序
生成树BFS 生成树/森林DFS 生成树/森林
连通分量BFS 调用次数 = 连通分量数DFS 调用次数 = 连通分量数

复杂度分析#

存储方式BFS 时间复杂度DFS 时间复杂度说明
邻接表O(V+E)O(V+E)每个顶点入队/入栈一次,每条边检查一次
邻接矩阵O(V2)O(V2)查找邻接顶点需扫描一整行

空间复杂度:O(V),主要为 visited 数组 O(V) 和辅助队列/递归栈 O(V)。

遍历序列的不唯一性#

遍历序列不唯一——邻接表的链表顺序不同会产生不同的遍历序列。用邻接矩阵则结果唯一(按下标顺序访问邻接点)。408 选择题常给出一个图和一个遍历序列,问”这个序列可能是 DFS/BFS 的结果吗”。


考研高频考点#

  • 给定图结构,写出 BFS/DFS 遍历序列
  • BFS 与 DFS 的对比:数据结构、适用场景、能否求最短路径
  • BFS 调用次数 = 连通分量个数
  • BFS 求无权图最短路径的 d[] 和 path[] 数组
  • DFS 检测有向图中是否有环(三色标记法)
  • 邻接表 vs 邻接矩阵对遍历时间复杂度的影响
  • 遍历序列不唯一性的原因分析

关联页面#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

图的遍历
https://lingluoa.icu/posts/graph-traversal/
作者
lingluoa
发布于
2026-07-07
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0