图中环检测算法 (DFS)
在图论中,环检测 (Cycle Detection) 是一个基础且重要的问题,用于判断一个有向图或无向图中是否存在环(也称为回路或循环)。图中的环是指一条路径,其起点和终点是同一个顶点。
本页面主要展示了基于深度优先搜索 (DFS) 的有向图环检测算法。该算法的核心思想是利用节点在 DFS 过程中的三种状态来判断是否存在"返祖边"(即指向当前 DFS 路径上已访问节点的边)。
- 对图中的每个尚未访问的节点,启动一次深度优先遍历。
- 在遍历过程中,维护每个节点的访问状态:
- 未访问 (UNVISITED): 节点从未被访问过。
- 正在访问 (VISITING): 节点已被访问,且其邻接点的探索尚未全部完成(即该节点在当前的 DFS 递归栈上)。
- 已访问 (VISITED): 节点及其所有邻居都已被完全探索完毕(即该节点已从 DFS 递归栈中弹出)。
- 当从节点
u
访问其邻居v
时:- 如果
v
是 未访问 状态,则递归地对v
进行 DFS。若在v
的子树中检测到环,则图存在环。 - 如果
v
是 正在访问 状态,则找到了一条从当前 DFS 路径指向路径中更早节点的边(返祖边),形成了一个环。 - 如果
v
是 已访问 状态,说明v
及其子树已被完全探索过且未发现指向当前路径的环,可以安全地忽略。
- 如果
- 如果遍历完所有节点都没有遇到指向"正在访问"状态节点的情况,则图中无环。
- 检测到的环的组成部分将用 红色/粉红色 标记。
对于无向图: 使用 DFS 检测无向图中的环时,需要额外注意。在从节点 u
访问邻居 v
时,如果 v
是"正在访问"状态,我们必须确保 v
不是 u
的直接父节点(即启动对 u
的 DFS 的那个节点)。否则,对于无向边 (u, v)
,从 u
到 v
再立即回到 u
会被错误地判断为环。通常在 DFS 函数中传递父节点 ID 来进行判断:if (neighbor != parent)
。
该算法对于有向图和无向图的时间复杂度均为 O(V + E),其中 V 是顶点数量,E 是边的数量。
提示:点击左上角的 ☰ 按钮可以查看 C++ 代码实现。
算法可视化交互
算法详细步骤:
图例:
未访问
正在访问
已访问
环中节点/边