图遍历基础

raw/articles/2026/05/图遍历基础

一句话总结

图的遍历就是 多叉树遍历 的延伸,主要遍历方式还是深度优先搜索(DFS)和广度优先搜索(BFS)。

唯一的区别是,树结构中不存在环,而图结构中可能存在环,所以我们需要标记遍历过的节点,避免遍历函数在环中死循环。

核心内容

三种遍历场景

由于图结构的复杂性,可以细分为遍历图的三种场景,每种场景的代码实现略有不同:

场景 标记数组 标记位置 说明
遍历节点 visited 一维数组 前序位置 确保每个节点只被遍历一次
遍历边 visited 二维数组 for循环内部 确保每条边只被遍历一次
遍历路径 onPath 数组 前序标记,后序撤销 记录当前路径,用于穷举所有路径

深度优先搜索(DFS)

图的 DFS 比多叉树遍历多了一个 visited 数组,用来记录被遍历过的节点,避免遇到环时陷入死循环。

为什么成环会导致死循环?

最简单的成环场景:1 <=> 2(双向边)。如果不标记遍历过的节点,遍历会陷入 1->2->1->2->... 无限递归。有了 visited 数组,第一次遍历到节点时标记,再次遇到已访问节点时直接返回,避免死循环。

基于邻接表/邻接矩阵的 DFS 代码框架:

// 遍历图的所有节点
void traverse(Graph graph, int s, boolean[] visited) {
    // base case
    if (s < 0 || s >= graph.size()) {
        return;
    }
    if (visited[s]) {
        // 防止死循环
        return;
    }
    // 前序位置
    visited[s] = true;
    System.out.println("visit " + s);
    for (Edge e : graph.neighbors(s)) {
        traverse(graph, e.to, visited);
    }
    // 后序位置
}

时间复杂度:$O(E + V)$,其中 $E$ 是边的总数,$V$ 是节点的总数。

为什么是 $O(E + V)$ 而不是 $O(V)$? 树结构中边的数量和节点数量近似相等,所以时间复杂度是 $O(N + N) = O(N)$。但图结构中任意两个节点之间都可以连接一条边,边的数量和节点的数量不再有特定关系,所以要同时考虑边和节点的数量。

遍历所有边(二维 visited 数组)

遍历所有边的场景并不多见,主要是计算欧拉路径时会用到。

核心思路:用二维 visited[u][v] 数组记录边 u->v 是否已被遍历,确保每条边只被遍历一次。

// 从起点 s 开始遍历图的所有边
void traverseEdges(Graph graph, int s, boolean[][] visited) {
    if (s < 0 || s >= graph.size()) {
        return;
    }
    for (Edge e : graph.neighbors(s)) {
        if (visited[s][e.to]) {
            continue;
        }
        visited[s][e.to] = true;
        System.out.println("visit edge: " + s + " -> " + e.to);
        traverseEdges(graph, e.to, visited);
    }
}

缺点:时间复杂度 $O(E + V^2)$,空间复杂度 $O(V^2)$。在讲解 Hierholzer 算法计算欧拉路径时会有优化方法。

遍历所有路径(onPath 数组)

图结构与树结构不同:树结构中从根节点到任意节点的路径唯一;图结构中可能存在多条路径。

遍历所有路径需要用 onPath 数组:

  • 前序位置:标记节点在路径上
  • 后序位置:撤销标记(节点离开路径)

这种方式可以穷举从起点到所有可达节点的路径,是计算最短路径等图论问题的基础。

相关概念

  • :图结构基础
  • 多叉树:图遍历的本质是多叉树遍历
  • DFS:深度优先搜索
  • BFS:广度优先搜索
  • 欧拉路径
  • Hierholzer算法

⚠️ 内容不完整说明

本文通过 defuddle 提取,内容被截断在"遍历所有路径"部分,缺失内容可能包括:

  • BFS 详细实现代码
  • BFS 与 DFS 的完整对比
  • onPath 数组的完整代码示例
  • 可视化面板说明

原始文章链接:https://labuladong.online/zh/algo/data-structure-basic/graph-traverse-basic/


Interactive Graph