An abstract syntax tree traversal systematically visits its nodes. A depth-first traversal of a tree that processes each child before its parent is called postorder. For the program expression 2+3*4, the schematic postorder is 2, 3, 4, Mult, Add. This order lets an evaluator obtain each operand value before applying its operation. A traversal of the entire Python schema additionally visits marker nodes such as Add and Store; this shorter list concerns only the expression nodes drawn in the figures. Visiting an abstract syntax tree is a structural operation, and is not a general model of execution: a conditional may select only one branch, while a structural visitor examines both.
Depth-first search Created 2026-10-13 Updated 2026-10-20
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
Inorder traversal 2026-10-13
An inorder traversal of a binary tree uses recursion to visit the left subtree, output the current vertex, and visit the right subtree; an empty subtree outputs nothing. This is a depth-first traversal of a tree with output between the two recursive calls. It produces sorted keys for a binary search tree, but arbitrary labels in a binary tree need not appear in total order.
// Target: computer-science.bigb
Write for the recursively repetition-free labelled trees. Each rooted tree is finite because the inductive definition forms it from an already constructed finite list of finite child rooted trees. Its label list is obtained by visiting the root first, then each child subtree in its prescribed order, using a depth-first traversal of a tree. This list can have repetitions. In particular, different branches may use the same label; the children are required to be distinct rooted trees, not to have distinct root labels.
For any finite label pool , prove by mathematical induction on that is finite. For it is empty. For each root , the children form a finite repetition-free sequence from , which is finite by mathematical induction. There are therefore finitely many child lists for that root, and the finite union over is finite. More explicitly, if is the number of rooted trees on a pool of labels, then
There is no countable choice in this finite mathematical induction.
Now suppose were an injective enumeration of a countably infinite subset of . Their canonical traversal lists give an explicit enumeration of all labels used. If infinitely many different labels occur, the least-first-occurrence procedure gives a countably infinite subset of , a contradiction. Otherwise all labels belong to one finite set . Every then belongs to : recursively its root lies in and its child rooted trees use only with that root removed. But is finite by the preceding mathematical induction, again a contradiction. Finally the single-vertex rooted tree labelled is injective, so is infinite. Hence recursively repetition-free labelled trees preserve Dedekind-finiteness:
Choose a spanning tree of , rooted at . A depth-first traversal of a tree gives a deterministic closed walk
that traverses each edge of once in each direction and visits every vertex. Define stopping times and
The simple random walk is at at time . All these hitting times have finite mean on the finite connected graph. By the Strong Markov property,
The cover time is no larger than . Grouping the summands by the two traversals of each tree edge and applying the commute time identity gives
The effective resistances are measured in the original graph, where each tree-edge pair is adjacent. Part (a) therefore bounds every summand by one, so
For the one-vertex graph, the cover time is zero and the same bound is immediate.
If is an infinite Dedekind-finite set, then is another such set. Single-vertex rooted trees inject into it. A countable sequence of distinct rooted trees gives finite lists of labels by the depth-first traversal of a tree in the prescribed child order. By countable union of explicitly ordered finite lists without choice, an infinite union of labels contradicts Dedekind-finiteness. A finite union is equally impossible, since every rooted tree then lies in the finite set , by mathematical induction on using the recursive child rule. Thus no countably infinite subset of rooted trees exists.
Rooted tree Created 2026-09-28 Updated 2026-10-14
A rooted tree is a tree with a distinguished vertex, its root of a tree . Choosing turns connections into a hierarchy: every other vertex has a unique parent in a rooted tree, the preceding vertex on its graph path from . Conversely, the vertices whose parent in a rooted tree is are the children in a rooted tree of . Choosing the root of a tree changes this description, while the underlying edges remain the same. Arrows towards the root of a tree can encode the relationship, as in MIT's counting notes; the undirected tree itself needs no arrows. [ref]
In the seven-vertex tree above, choose . The levels, grouped by graph distance from the root of a tree, are , , , . The children in a rooted tree of are , and the parent in a rooted tree of is . Choosing instead makes the levels , , , , , : now has parent in a rooted tree , reversing their relationship. All six edges survive.
This hierarchy supports structural recursion: process the smaller rooted trees below each vertex, then combine their results. A depth-first traversal of a tree explores one branch before returning; breadth-first search processes successive levels. The lowest common ancestor identifies where two routes from the root of a tree last coincide. For it is when . A binary tree imposes an additional restriction on children in a rooted tree; a general rooted tree has no such bound.