function dfs(graph: Graph, node: Node, seen = new Set<Node>()) {seen.add(node);
visit(node);
for (const neighbor of graph.neighbors(node)) {if (seen.has(neighbor)) continue;
dfs(graph, neighbor, seen);
}
return seen;
}
Visit A at depth 0.
Understanding DFS
The idea
Depth-first search goes as deep as it can before it goes wide: from the current node it picks the first unvisited neighbour, recurses into it, and only when a node has no unvisited neighbours does it return to whoever called it. The call stack is the path from the source to the current node.
The order nodes are entered and left carries structure: entry and exit times classify every edge as tree, back, forward or cross, which is what cycle detection, topological sorting and Tarjan's strongly connected components are built on.
The four stages
Complexity
Versus its siblings
Pseudocode
DFS(graph, node)
mark node visited; visit(node)
for each neighbour of node
if neighbour not visited: DFS(graph, neighbour)
When to use
Pitfalls
History
Trémaux's 19th-century rule for walking a maze is depth-first search in disguise. John Hopcroft and Robert Tarjan made it the workhorse of graph algorithms in 1973, showing linear-time planarity testing and biconnected components with nothing but DFS and a few timestamps.