图中环检测算法 (DFS)

在图论中,环检测 (Cycle Detection) 是一个基础且重要的问题,用于判断一个有向图或无向图中是否存在环(也称为回路或循环)。图中的环是指一条路径,其起点和终点是同一个顶点。

本页面主要展示了基于深度优先搜索 (DFS) 的有向图环检测算法。该算法的核心思想是利用节点在 DFS 过程中的三种状态来判断是否存在"返祖边"(即指向当前 DFS 路径上已访问节点的边)。

  1. 对图中的每个尚未访问的节点,启动一次深度优先遍历。
  2. 在遍历过程中,维护每个节点的访问状态
    • 未访问 (UNVISITED): 节点从未被访问过。
    • 正在访问 (VISITING): 节点已被访问,且其邻接点的探索尚未全部完成(即该节点在当前的 DFS 递归栈上)。
    • 已访问 (VISITED): 节点及其所有邻居都已被完全探索完毕(即该节点已从 DFS 递归栈中弹出)。
  3. 当从节点 u 访问其邻居 v 时:
    • 如果 v未访问 状态,则递归地对 v 进行 DFS。若在 v 的子树中检测到环,则图存在环。
    • 如果 v正在访问 状态,则找到了一条从当前 DFS 路径指向路径中更早节点的边(返祖边),形成了一个环。
    • 如果 v已访问 状态,说明 v 及其子树已被完全探索过且未发现指向当前路径的环,可以安全地忽略。
  4. 如果遍历完所有节点都没有遇到指向"正在访问"状态节点的情况,则图中无环。
  5. 检测到的环的组成部分将用 红色/粉红色 标记。

对于无向图: 使用 DFS 检测无向图中的环时,需要额外注意。在从节点 u 访问邻居 v 时,如果 v 是"正在访问"状态,我们必须确保 v 不是 u 的直接父节点(即启动对 u 的 DFS 的那个节点)。否则,对于无向边 (u, v),从 uv 再立即回到 u 会被错误地判断为环。通常在 DFS 函数中传递父节点 ID 来进行判断:if (neighbor != parent)

该算法对于有向图和无向图的时间复杂度均为 O(V + E),其中 V 是顶点数量,E 是边的数量。

提示:点击左上角的 ☰ 按钮可以查看 C++ 代码实现。

算法可视化交互

算法详细步骤:
请在画布上添加节点和边,或加载示例图。
图例:
未访问
正在访问
已访问
环中节点/边

画布交互:

控制按钮:

注意: 页面目前未实现撤销/重做功能。