Graph DFS
Traverse a graph by exploring as deep as possible before backtracking.
The Mathematics
Depth-first exploration, stack structure, and edge classification
Core Idea
DFS explores a graph by going as deep as possible along each branch before backtracking. It uses a stack (implicit via recursion or explicit):
DFS vs. BFS
While BFS uses a FIFO queue (layer-by-layer), DFS uses a LIFO stack (depth-first). BFS finds shortest paths in unweighted graphs; DFS is useful for topological sorting, cycle detection, and connected components.
BFS
Layer-by-layer
DFS
Depth-first
Edge Classification
DFS classifies edges in the graph:
Tree edges: edges in the DFS tree (to unvisited vertices)
Back edges: edges to an ancestor (indicate a cycle)
Forward/Cross edges: edges to already-finished vertices
Complexity
Every vertex is visited exactly once, and every edge is examined once (twice for undirected graphs):
Same asymptotic complexity as BFS, but the traversal order is fundamentally different.
See It Work
DFS traversal from node A — watch the recursive stack
Call Stack (LIFO)
Start DFS from node A. Mark A as visited and begin exploring.
The Code
Mapping recursive DFS to Python with a nested explore function
Mathematical Formulation
Initialize empty visited set to track explored vertices
Mark the current vertex as visited
Iterate over all neighbors of the current vertex
Recursively explore unvisited neighbors — go deep first
Each vertex visited once, each edge checked once
Python Implementation
def dfs(graph, source):
visited = set()
order = []
def explore(v):
visited.add(v) # Mark visited
order.append(v) # Record order
for u in graph[v]: # Visit neighbors
if u not in visited: # Skip if seen
explore(u) # Recurse deeper
explore(source)
return order