Proofs: Depth-first search
These are the human proofs of Depth-first search, at full length.
Depth-first search visits each vertex once and finds the reachable set full
This proof shows: correctness, termination.
Let be a directed or undirected graph with vertices, where an undirected edge is in both adjacency lists. We say that a call DFS-VISIT is active from its start at line L5 to its end at line L10. A call that starts while another call is active ends before that call ends, because calls nest as on any call stack.
Lemma 1 (one call for each vertex). During DFS, DFS-VISIT is called exactly one time for each . A vertex is white before its call, gray while its call is active, and black after it. The run stops, and the times and over all are the numbers , each used one time, with .
Proof. Only line L5 makes a vertex gray, only line L10 makes it black, and no line makes a vertex white after line L1. So the colour of each vertex goes from white to gray to black, and never back. A call DFS-VISIT is made at line L4 or line L9 only after the test that is white, and its first line makes gray. So there is at most one call for each . The loop of line L3 tests each vertex, and it calls DFS-VISIT on each vertex that is still white. So after the loop, each vertex had its call, and there are exactly calls.
Each call does a finite loop over besides its own nested calls, and there are only calls in total, so the run stops. Each call increases by 1 at line L5 and by 1 at line L10, and it stores the new value in and . Nothing else changes , which starts at 0. So the increases give the values , each stored one time. In each call, line L5 runs before line L10, so .
Lemma 2 (the gray vertices). At each moment, the gray vertices are exactly the vertices with an active call. If they are in the order of their calls, then was called at line L4, and for .
Proof. The first statement is Lemma 1. The active calls are the calls on the call stack, from the bottom to the top . The bottom call comes from line L4, because a call from line L9 is made while another call is active. For , the call of was made at line L9 of the call of , which is the call just below it on the stack, and line L8 set just before.
Lemma 3 (the forest). When DFS stops, $\pi[v] = $ NIL exactly for the vertices called at line L4. For each other vertex , and . So the edges form a forest, and each of its trees has one root called at line L4.
Proof. Line L1 sets each parent to NIL, and only line L8 changes . Line L8 runs for only when is white, just before the call of at line L9, so it runs at most one time for each , and exactly for the vertices called at line L9. These are the vertices not called at line L4, by Lemma 1. At that moment, the call of is active and , so , and is already set while is set later, so . Along the chain the discovery time decreases strictly, so the chain has no repeated vertex and it ends at a vertex with parent NIL. So the parent edges contain no cycle, and each vertex is joined to exactly one root.
Lemma 4 (reachability). Let all vertices be white, and call DFS-VISIT. Let be the set of vertices discovered during this call, and let be the set of vertices reachable from . Then .
Proof. First . We use induction on the order of discovery. The first vertex of is . A later vertex is discovered at line L9 in the call of some vertex with . This call of is active during the call of , so it started during the call of or it is the call of . So , and was discovered before . By the induction hypothesis , and the edge gives .
Now . Assume that some is not in . Take a path in , and let be the least index with . Then because , and . The call of started during the call of , or is it, so it ends before the call of ends. In this call, the loop of line L6 reaches , because . If is white at that moment, line L9 calls DFS-VISIT during the call of , so . If is not white, it was discovered before that moment. All vertices were white when the call of began, so was discovered after that, and before the moment, which is during the call of . So again. Both cases contradict the choice of .
Theorem. DFS stops after calls of DFS-VISIT. It gives each vertex one discovery time and one finish time, the times are , and the parent pointers form a forest of edges of whose roots are the vertices picked at line L4. A single call DFS-VISIT on a graph with all vertices white discovers exactly the vertices reachable from , and the parent pointers then give a path of from to each of them.
Proof. The first part is Lemmas 1 and 3. The second part is Lemma 4. For the paths, follow the parent pointers from a vertex . By Lemma 3, each step goes back along an edge of to a vertex with a smaller discovery time, and by the first half of the proof of Lemma 4 each such vertex is in . The chain ends at the only vertex of with parent NIL, which is . Read backwards, it is a path from to .
The white-path theorem extends Lemma 4 to each call of DFS-VISIT, also when some vertices are no longer white, and the parenthesis theorem describes how the intervals nest.