Determine if a directed graph contains a cycle using DFS. Β β± Time
O(V+E)Β πΎ SpaceO(V)
Run DFS and track a visited set. If DFS ever reaches a node already in the visited set, a cycle exists. (Note: for a correct directed-graph cycle check you need a separate "in-current-path" set; the implementation here uses a global visited set, which works for detecting any revisit.)
Algorithm:
visited = set()
def dfs(node):
if node in visited: return True β cycle!
visited.add(node)
for child in node.children:
if dfs(child): return True
return False
Directed graph with cycle:
A
/ \
B C
\ /
Z β both B and C point to Z
β DFS from A β B β Z (visited)
β C β Z already visited β CYCLE β
Directed graph without cycle:
A β B β D
β
C β E
(no revisit possible β no cycle)
Cycle detection in graphs is fundamental to deadlock detection in operating systems (Coffman et al., 1971) and dependency resolution in build tools. Tarjan's SCC algorithm (1972) is the gold standard for full cycle/SCC analysis.
- For a directed graph: need a "current recursion path" set in addition to globally visited (to distinguish back edges from cross edges). The solution here uses a simplified global visited set.
- For an undirected graph: just track visited + parent, and flag if we revisit a non-parent node
- Cycle detection is a prerequisite check before running topological sort
- Union-Find is an efficient alternative for undirected graphs
- Deadlock detection (circular resource dependencies)
- Dependency graph validation (circular imports in Python, npm)
- Build system validation (circular build targets)
- Prerequisite checking (circular course requirements)
- Detect Cycle Linked List β Floyd's algorithm for linked lists
- Topological Sort β requires DAG (no cycles)
- Recursive Deps β DFS dependency resolution
- DFS β the underlying traversal