The goal of Depth First Search is to search as ‘deep’ into the graph as possible, which is opposed to Breadth First Search which is to search as ‘wide’ as possible. In DFS, edges are explored out of the most recently discovered vertex v that has unexplored edges out of it. When all of v’s edges have been explored, the search “backtracks” to explore other edges leaving the source vertex from which v was discovered. This process is continued until all the vertices reachable from the original source vertex have been discovered. If any undiscovered vertices remain, then one of them is selected as a new source and the search is repeated from that source. This process is repeated until all vertices have been discovered.
Unlike BFS, where the predecessor subgraph forms a tree, the predecessor subgraph formed by a DFS may be composed of several trees to form a DFS forest. This is because the search may be repeated from multiple sources.
As in BFS, vertices are colored during ths search to indicate their state. Each vertex is initially white, is grayed when it is discovered in the search and blackened when finished, i.e. when it’s adjacency list/neighbor set has been examined completely. This guarantees that each vertex ends up in exactly one depth-first tree so that these trees are disjoint.
Besides creating a depth-first forest, depth-first search also timestamps each vertex. Each vertex v has 2 timestamps: the 1st timestamp disc[v] records when v is first discovered and grayed, and the 2nd timestamp fin[v] records when the search finishes examining v’s adjacency list and blackens v.
The pseudocode is as follows:
DFS(G) 1 for each vertex u in V[G] 2 do color[u] <--- WHITE 3 pred[u] <--- NULL 4 time <--- 0 5 for each vertex u in V[G] 6 do if color[u] == WHITE 7 then DFS-VISIT(u) DFS-VISIT 1 color[u] <--- WHITE // White vertex u has just been discovered. 2 time <--- time + 1 3 disc[u] <-- time 4 for each v in Adj[u] // Explore edge (u,v) 5 do if color[v] == WHITE 6 then pred[v] <--- u 7 DFS-VISIT(v) 8 color[u] <-- BLACK // Blacken u; it is finished 9 fin[u] <--- time <--- time +1
Total running time is: θ(V+E). DFS runs linear in the size of the adjacency list representation of the graph G.