Depth-first search is a graph search that follows a branch as far as it can before returning to try the next unexplored branch. Starting at a vertex of an undirected graph on a finite set of vertices, mark as discovered. Scan its graph neighbours in a fixed order: for each undiscovered vertex, record the current vertex as its parent in a rooted tree in the discovery tree, mark the new vertex, and explore it immediately using recursion. Return when its adjacency list is exhausted. Discovery marks persist after return, preventing a graph cycle from causing repeated exploration. This branch-and-return rule is the maze exploration described in MIT's notes. [ref]
Use the same unweighted undirected graph as breadth-first search, with vertex set and edges
where denotes the unordered pair . Visit graph neighbours in lexicographic order of their one-letter labels, starting at . The discovery order, computed by the diagram's generator, is
The discovery edges in order are . They form a rooted tree spanning the reached vertices, with root of a tree . The other edges, and , remain in the original graph but never discover a new vertex. In particular, the graph cycle causes no repeated discovery.
Figure 1.
Depth-first search: discovery edges and the active call stack on seven vertices
. Numbers show first-discovery order. Solid edges form the discovery tree; dashed edges belong only to the original graph. The right panel shows the call stack from oldest call to current call, including the return from before entering . Details.
At there is no undiscovered graph neighbour, so its call returns to . The next call enters , then , then , then . Immediately after discovering , the call stack is , with on top; is still discovered but its call has finished. The maximum call stack depth is six, although seven vertices are discovered. Following the recorded parent in a rooted tree backwards at each step reconstructs a graph path; here the route from to is , using five edges. Breadth-first search instead finds , using three edges. Depth-first search establishes reachability but does not guarantee the fewest edges.
An explicit LIFO stack can replace recursion, but its entries and discovery rule must be specified. To reproduce this exact traversal, store one frame per active vertex, retaining the next position in its adjacency list. Advance the top frame by one graph neighbour; if that vertex is undiscovered, mark it and push its frame immediately; pop an exhausted frame. Pushing all undiscovered graph neighbours at once and marking them on push is a different iterative variant. Even pushing them in reverse lexicographic order does not generally reproduce the parent in a rooted tree relationships above: would already be marked while processing , so could not discover .
With an adjacency list representation, constant-cost discovery checks and frame operations, and the graph neighbours already ordered, depth-first search has time complexity in Big O notation. Each reached vertex is entered once and each incident edge is examined at most twice in an undirected graph; initializing all discovery marks costs . The call stack has depth at most , since no active vertex repeats. Discovery marks and the recorded parent in a rooted tree for each nonroot vertex also need auxiliary space complexity, excluding storage for the graph. Sorting adjacency lists to obtain a chosen order is additional work. [ref]
One start explores only its connected component of a graph. To cover a disconnected graph, start again at every still-undiscovered vertex while keeping all discovery marks; the discovery trees form a forest. Depth-first search is useful for reachability, constructing a spanning tree of a connected graph, and organizing the return steps needed by a depth-first traversal of a tree. For detecting a graph cycle in a simple graph that is an undirected graph, an edge to an already discovered vertex other than the current parent in a rooted tree closes a graph cycle; the immediate return edge to that parent in a rooted tree is not itself a graph cycle.
// Target: computer-science.bigb
The discovery-to-finishing intervals of distinct vertices in a depth-first search are either disjoint or strictly nested. A recursive call completes before its caller returns; separate completed branches have disjoint intervals. Thus the displayed nesting holds exactly when is a proper descendant in a rooted tree of in the discovery forest. A directed path alone does not imply this nesting, because it can leave the current branch through an already discovered ancestor.
A cost-bounded depth-first search follows the usual depth-first search order but immediately rejects a generated search node whose accumulated path cost exceeds a threshold . It can also return the least rejected path cost, providing the next threshold for iterative lengthening search. Positive step costs ensure that a rejected prefix cannot become a cheaper extension. With finite branching factor and every step costing at least , every admitted search node has search depth at most , so the pass terminates. Merely requiring every individual step cost to be positive does not exclude an infinite branch of finite total path cost.
An explicit-stack depth-first tree traversal stores pending subtree roots instead of suspended recursive calls. In a binary tree, visit the current node, defer its nonempty right child on a stack, and continue with its left child; pop when the current subtree is empty. The unvisited subtrees remain disjoint and, together with the visited nodes, partition the original tree. This loop invariant proves that accumulating each visited label gives the tree sum. At most one right sibling per ancestor is pending, so auxiliary storage is for depth and running time is for nodes. Unlike a full recursive stack frame, a pending entry need contain only a subtree pointer.
Classify directed edges relative to a depth-first search forest. Tree edges discover a new vertex; forward edges reach a proper descendant without being its discovery edge; back edges reach an active ancestor; cross edges connect completed branches or trees. Discovery and finish intervals are nested for ancestry. The classification depends on the chosen search order, not only on the graph.
A directed edge whose endpoints have no ancestor-descendant relationship in the depth-first search forest. Their discovery-to-finishing intervals are disjoint by the DFS parenthesis property. Such an edge can connect different completed branches or different search trees.
A directed edge whose examination first discovers its target and recursively enters it. It becomes the target's parent edge in the depth-first search forest.
A directed edge from a vertex to an active ancestor in its depth-first search. Together with the tree path from that ancestor it witnesses a directed cycle.
A directed edge to a proper descendant in the depth-first search forest that is not a tree edge. Its endpoints satisfy .
A traversal clock incremented on each vertex discovery and finish records two times per vertex. The active recursion interval of an ancestor contains that of each descendant. A finished vertex has no unexamined outgoing edge. These facts constrain possible finishing orders even when traversal order is unspecified.
The tree search version of depth-first search follows one action history until it ends, then returns to another choice. Repeated states do not automatically stop a branch. An infinite branch can prevent discovery of a goal on a different finite branch, so this method is not generally a complete search algorithm. A finite search tree restores completeness, but the first successful history need not minimize cost or maximize a terminal reward.
Repeat a depth-limited depth-first search with successively larger depth limits. With unit-cost steps, the first successful depth is the minimum number of steps, provided each depth-limited search is complete. Each pass stores only the current path and its search bookkeeping.

Ancestors (3)

  1. Algorithm
  2. Computer science
  3. Home

Synonyms (2)

Discussion (0) New discussion

There are no discussions about this article yet.

Articles by others on the same topic (2)

Depth-first search (DFS) is an algorithm used for traversing or searching through tree or graph data structures. The algorithm starts at a selected node (often referred to as the "root" in trees) and explores as far as possible along each branch before backtracking. This method allows DFS to explore deep into a structure before returning to explore other nodes.