Depth-First Search
Go deeper whenever you can! Edges are explored out from the
most recently discovered vertices, v, with outgoing edges. When all of v's
edges have been explored you "back track" to explore edges leaving
the vertex where v was discovered. If there are undiscovered vertices, you
restart from there. When v is discovered while scanning Adj[u]: p[v]
= u (like BFS) But the predecessor sub graph (not a tree) is Gp
= ( V, Ep ) Ep
= { ( p[v], v ): v Î V
and p[v] ¹ nil
}
Several trees: Gp
called a depth-first forest made up of many d-f trees (several
starting points.) Vertices are colored as in BFS. Depth-first search time
stamps each vertex.
d[v] : when grayed
f[v] : when blackened
1 £ d[v], f[v] £
2 | V | as one d and one f event for each vertex. d[v] < f[u]
white, d[v] gray, f[u] black. Ordering of the events is the same, locally,
but different globally with BFS.
DFS ( G )
-
for each vertex u Î V[G]
-
do color[u] ¬ white
-
p[u]
¬ nil // initialization
-
time ¬ 0
-
for each vertex u Î V[G]
-
do if color[u] = white
-
then DFS-Visit (u)
// start from each white
DFS-Visit (u)
-
color[u] ¬ gray //
white vertex has just been discovered
-
d[u] ¬ time ¬
time + 1
-
for each v Î Adj[u] //
explore edge ( u, v )
-
do if color[v] = white
-
then p[v]
¬ u
-
DFS-Visit
(v)
-
color[u] ¬ black
// Blackened u; it is finished
-
f[u] ¬ time ¬
time + 1
Note: no Q, recursion instead. d[u] is enqueuing, f[u] is
dequeuing.
Running time DFS O ( | V | ). DFS-Visit
S | Adj[u] |. Overall O ( | V | +
| E | ) same as BFS.
Properties of DFS:
-
Gp , DFS
predecessor sub graph is a "forest" of trees and exactly
represents the calls to DFS-Visit, which is recursive.
-
The discovery time d[u] and finish time f[u] have the
parenthesis property
Note: the expression in figure b is well formed since the
p's are properly nested.
Parenthesis Theorem:
In a DFS of G for u, v Î V
[ d[u], f[u] ] = I1 V [ d[v], f[v] ] =
I2 . Either:
-
I1 Ç
I2 = Æ
-
I1 Ì I2
or
-
I2 Ì
I1
(proof is from the recursive nature of DFS-Visit.)
Nesting of Descendant's Intervals:
If v is a proper descendant of u in a DF Forest (same
tree) iff d[u] < d[v] < f[v] < f[u].
White-path Theorem:
In a DF Forest of G = ( V, E ) v is a descendant of
u Û at d[u] (when u is discovered) v can be
reached ffrom u along a path that is all white.
Proof: AT d[u], v hasn't been discovered, and so all is
white in between.
Edges in DFS:
Tree Edges: edges in Gp
( u, v ) if v was discovered first via ( u, v ).
Back Edges: ( u, v ) v is an ancestor of u (also self
loops).
Forward Edges: ( u, v ) v a descendant but ( u, v )
not a Tree.
Cross Edges: All others
Can modify DFS to categorize the edges by color of vertex
when first encountered:
white: tree
gray: back
black: forward
Last Theorem: In a DFS of G, undirected, every edge of G is
either a tree or back edge. Proof: See book.
|