Trees
Trees and forests, rooted trees, binary trees, preorder, inorder, postorder and level order, expression trees, and spanning trees
The topics of this chapter follow the course calendar, and their order follows Kameron Decker Harris’s Fall 2026 lecture notes on trees. These come from those notes:
- a tree as a connected graph with no cycles (the notes say no simple circuits), and a forest, whose connected components are trees;
- the theorem that a graph is a tree if and only if there is exactly one path between every two of its vertices;
- rooted trees, with the root, parents, children, ancestors, descendants, leaves, internal vertices and subtrees, and the fact that choosing a different root gives a different rooted tree;
- the level of a vertex and the height of a rooted tree;
- ordered rooted trees, and binary trees, with their left and right subtrees;
- the theorem that a tree with \(n\) vertices has \(n - 1\) edges;
- preorder, inorder and postorder traversal;
- expression trees, and the infix, prefix (Polish) and postfix (reverse Polish) forms of an expression, with parentheses needed only in the infix form;
- spanning trees, the theorem that a graph is connected if and only if it has a spanning tree, and the spanning trees that depth-first and breadth-first search build.
The notes define the traversals for ordered rooted trees, by pseudocode; here they are defined recursively for binary trees, as lists, and a remark extends preorder and postorder to ordered rooted trees. In the notes a forest is not connected; here a forest is any graph with no cycles, so a tree is a forest too. The notes’ \(m\)-ary trees, full \(m\)-ary trees, balanced trees, and the counting theorems for them, siblings, back edges, and spanning forests of directed graphs are left out. A bound on the number of vertices of a binary tree of a given height is in their place. The definition of a parse tree is included from the mathematics prerequisites notes, so it reads the same in both places. Level order, as breadth-first search from the root, follows the course calendar’s “tree traversal”. The proof that a tree with \(n\) vertices has \(n - 1\) edges, the other proofs, the examples, the exercises and the Racket functions are new.
1 Trees
Proof. Let \(v_0, e_1, v_1, \ldots, e_n, v_n\) be a cycle of \(G\), with \(v_n = v_0\). Each of its vertices has degree at least 2. If \(n = 1\), then \(e_1\) is a loop (Definition: Loop) at \(v_0\), which counts twice in \(\deg(v_0)\). If \(n \ge 2\), then each \(v_i\) is an endpoint of two edges of the cycle, the edge just before it and the edge just after it (for \(v_0\), these are \(e_n\) and \(e_1\)), and these two edges are different, since a cycle is a trail (Definition: Trail). So \(v\) is not on the cycle. The edge of \(v\) is not on the cycle either, since every edge of the cycle has its endpoints on the cycle. So the cycle is a cycle of \(H\).
For the second statement, each step keeps every cycle, so a cycle of \(G\) would be a cycle of the last graph, which has no edges and so no cycles.
Proof. A tree has exactly one path between two vertices. Let \(G\) be a tree, and let \(u\) and \(v\) be vertices of \(G\). Since \(G\) is connected (Definition: Connected graph), there is a walk from \(u\) to \(v\), so there is a path from \(u\) to \(v\), by Theorem: A shortest walk is a path.
Suppose, for contradiction (Definition: Proof by contradiction), that there are two different paths from \(u\) to \(v\), written by their vertices (Remark 1) as
\[ \begin{aligned} u &= p_0, p_1, \ldots, p_m = v, \\ u &= q_0, q_1, \ldots, q_k = v. \end{aligned} \]
If \(p_j = q_j\) for every \(j \le \min(m, k)\), the paths are the same: if \(m < k\), then \(q_m = p_m = v = q_k\) would repeat a vertex of the second path, and \(k < m\) is ruled out in the same way. So there is a smallest \(j \ge 1\) with \(p_j \ne q_j\). Let \(i = j - 1\), so that \(p_i = q_i\) and \(p_{i + 1} \ne q_{i + 1}\).
The vertex \(p_m = v = q_k\) of the first path is one of \(q_{i + 1}, \ldots, q_k\). Let \(a > i\) be the smallest index for which \(p_a\) is one of \(q_{i + 1}, \ldots, q_k\), say \(p_a = q_b\) with \(b > i\). Then
\[ p_i, p_{i + 1}, \ldots, p_a = q_b, q_{b - 1}, \ldots, q_{i + 1}, q_i = p_i \]
is a closed walk from \(p_i\) to itself. Its vertices before the last one are all different: \(p_i, \ldots, p_a\) are vertices of a path, and so are \(q_{b - 1}, \ldots, q_{i + 1}, q_i\); by the choice of \(a\), none of \(p_{i + 1}, \ldots, p_{a - 1}\) is one of \(q_{i + 1}, \ldots, q_{b - 1}\); \(p_a = q_b\) is not one of \(q_{i + 1}, \ldots, q_{b - 1}\); and \(p_i = q_i\) is not one of \(q_{i + 1}, \ldots, q_{b - 1}\). Its length is \((a - i) + (b - i) \ge 3\), since both terms are at least 1, and \(a = b = i + 1\) would give \(p_{i + 1} = q_{i + 1}\). Each edge of the closed walk joins two consecutive vertices, and since there are at least three vertices before the last one, all different, no two of these pairs of consecutive vertices are the same set. So the edges are all different, and the closed walk is a cycle (Definition: Cycle), which contradicts that \(G\) is a tree. So there is exactly one path from \(u\) to \(v\).
A graph with exactly one path between every two vertices is a tree. Suppose that \(G\) has no loops and exactly one path between every two vertices. A path is a walk, so \(G\) is connected. Suppose, for contradiction, that \(G\) has a cycle \(v_0, e_1, v_1, \ldots, e_n, v_n\), with \(v_n = v_0\). Then \(n \ge 2\), since a cycle of length 1 is a loop. Both
\[ \begin{aligned} & v_0, e_1, v_1, \\ & v_0, e_n, v_{n - 1}, e_{n - 1}, \ldots, e_2, v_1 \end{aligned} \]
are paths from \(v_0\) to \(v_1\), since the vertices \(v_0, \ldots, v_{n - 1}\) of the cycle are all different. They are different paths: if \(n \ge 3\), the first has length 1 and the second has length \(n - 1 \ge 2\), and if \(n = 2\), they use the edges \(e_1\) and \(e_2\), which are different since a cycle is a trail (Definition: Trail). This contradicts that there is exactly one path from \(v_0\) to \(v_1\). So \(G\) has no cycles, and \(G\) is a tree.
2 Rooted trees
Proof. Let \(r\) be the root, and let \(r = p_0, p_1, \ldots, p_m = u\) be the path from \(r\) to \(u\) (Theorem 1). Also \(w \ne u\), since a tree has no loops (Remark 1).
- If \(w\) is not on this path, then \(p_0, \ldots, p_m, w\) is a path from \(r\) to \(w\), since its vertices are all different and \({\mathopen{}\left\{u, w\right\}\mathclose{}}\) is an edge. By Theorem 1 it is the path from \(r\) to \(w\), so \(u\) is the parent of \(w\).
- If \(w\) is on this path, then \(w = p_i\) for some \(i < m\). If \(i = m - 1\), then \(w\) is the parent of \(u\). Suppose, for contradiction (Definition: Proof by contradiction), that \(i \le m - 2\). Then \(p_i, p_{i + 1}, \ldots, p_m, p_i\), whose last step uses the edge \({\mathopen{}\left\{u, w\right\}\mathclose{}}\), is a closed walk of length \(m - i + 1 \ge 3\) whose vertices before the last one are all different. As in the proof of Theorem 1, its edges are all different, so it is a cycle (Definition: Cycle), which a tree does not have.
Proof. Let \(r = v_0, v_1, \ldots, v_k = v\) be the path from \(r\) to \(v\), so that \(u = v_{k - 1}\). The vertices \(v_0, \ldots, v_{k - 1}\) are all different, so \(v_0, \ldots, v_{k - 1}\) is a path from \(r\) to \(u\), and by Theorem 1 it is the path from \(r\) to \(u\). Its length is \(k - 1\), so \(\operatorname{level}(u) = k - 1 = \operatorname{level}(v) - 1\) (Definition 11).
3 Counting edges
Proof. Choose any vertex \(r\) of \(T\) as a root (Definition 3). For each vertex \(v \ne r\), let \(e(v)\) be the edge joining \(v\) to its parent (Definition 4) \(u\), which is an edge since \(u\) and \(v\) are consecutive vertices of a path.
Every edge is \(e(v)\) for some \(v\). By Lemma 2, one endpoint of each edge is the parent of the other endpoint \(v\), and then the edge is \(e(v)\).
Different vertices give different edges. Suppose, for contradiction (Definition: Proof by contradiction), that \(e(v) = e(w)\) for two vertices \(v \ne w\). The endpoints of this edge are \(v\) and its parent, and also \(w\) and its parent, so \(w\) is the parent of \(v\) and \(v\) is the parent of \(w\). By Lemma 3,
\[ \operatorname{level}(v) = \operatorname{level}(w) + 1 = \operatorname{level}(v) + 2, \]
which is false.
So, listing the \(n - 1\) vertices other than \(r\) as \(v_1, \ldots, v_{n - 1}\), the list \(e(v_1), \ldots, e(v_{n - 1})\) has each edge of \(T\) exactly once, and \({\mathopen{}\left|E\right|\mathclose{}} = n - 1\) (Definition: Cardinality).
4 Binary trees
Proof. We use structural induction (Definition: Structural induction) on \(T\).
Base case. \(\operatorname{size}(\mathtt{nil}) = 0 = 2^{-1 + 1} - 1\).
Inductive step. Let \(T = \operatorname{node}(x, L, R)\), where \(L\) and \(R\) satisfy the inequality, and let \(h = \operatorname{height}(T)\). By Remark 7, \(\operatorname{height}(L) \le h - 1\) and \(\operatorname{height}(R) \le h - 1\). Then, using the formula for size in Remark 7 first,
\[ \begin{aligned} \operatorname{size}(T) &= 1 + \operatorname{size}(L) + \operatorname{size}(R) && \text{(formula for size)} \\&\le 1 + \mathopen{}\left(2^{\operatorname{height}(L) + 1} - 1\right)\mathclose{} + \mathopen{}\left(2^{\operatorname{height}(R) + 1} - 1\right)\mathclose{} && \text{(induction hypothesis)} \\&\le 1 + \mathopen{}\left(2^{h} - 1\right)\mathclose{} + \mathopen{}\left(2^{h} - 1\right)\mathclose{} \\&= 2^{h + 1} - 1. \end{aligned} \]
By structural induction, the inequality holds for every binary tree.
5 Preorder, inorder and postorder
Proof. We use structural induction (Definition: Structural induction) on \(T\).
Base case. All three traversals of \(\mathtt{nil}\) are \(\mathtt{empty}\), of length \(0 = \operatorname{size}(\mathtt{nil})\).
Inductive step. Let \(T = \operatorname{node}(x, L, R)\), where the three lengths for \(L\) are \(\operatorname{size}(L)\) and those for \(R\) are \(\operatorname{size}(R)\). By Theorem: Appending adds lengths and the definition of \(\operatorname{len}\), for the preorder (Definition 15),
\[ \begin{aligned} & \operatorname{len}\mathopen{}\left(\operatorname{preorder}(T)\right)\mathclose{} \\&= 1 + \operatorname{len}\mathopen{}\left(\operatorname{app}\mathopen{}\left(\operatorname{preorder}(L), \operatorname{preorder}(R)\right)\mathclose{}\right)\mathclose{} \\&= 1 + \operatorname{len}\mathopen{}\left(\operatorname{preorder}(L)\right)\mathclose{} + \operatorname{len}\mathopen{}\left(\operatorname{preorder}(R)\right)\mathclose{} \\&= 1 + \operatorname{size}(L) + \operatorname{size}(R), \end{aligned} \]
for the inorder (Definition 16),
\[ \begin{aligned} & \operatorname{len}\mathopen{}\left(\operatorname{inorder}(T)\right)\mathclose{} \\&= \operatorname{len}\mathopen{}\left(\operatorname{inorder}(L)\right)\mathclose{} + \operatorname{len}\mathopen{}\left(\operatorname{cons}\mathopen{}\left(x, \operatorname{inorder}(R)\right)\mathclose{}\right)\mathclose{} \\&= \operatorname{len}\mathopen{}\left(\operatorname{inorder}(L)\right)\mathclose{} + 1 + \operatorname{len}\mathopen{}\left(\operatorname{inorder}(R)\right)\mathclose{} \\&= \operatorname{size}(L) + 1 + \operatorname{size}(R), \end{aligned} \]
and for the postorder (Definition 17),
\[ \begin{aligned} & \operatorname{len}\mathopen{}\left(\operatorname{postorder}(T)\right)\mathclose{} \\&= \operatorname{len}\mathopen{}\left(\operatorname{postorder}(L)\right)\mathclose{} + \operatorname{len}\mathopen{}\left(\operatorname{app}\mathopen{}\left(\operatorname{postorder}(R), \operatorname{cons}(x, \mathtt{empty})\right)\mathclose{}\right)\mathclose{} \\&= \operatorname{len}\mathopen{}\left(\operatorname{postorder}(L)\right)\mathclose{} + \operatorname{len}\mathopen{}\left(\operatorname{postorder}(R)\right)\mathclose{} + \operatorname{len}\mathopen{}\left(\operatorname{cons}(x, \mathtt{empty})\right)\mathclose{} \\&= \operatorname{size}(L) + \operatorname{size}(R) + 1. \end{aligned} \]
Each of these is \(\operatorname{size}(T)\), by Remark 7. By structural induction, the equations hold for every binary tree.
6 Level order
Proof. Let \(I\) be the statement that, if \(x_1, \ldots, x_k\) are the vertices in the queue \(Q\) from front to back, then
\[ \texttt{dist}[x_1] \le \texttt{dist}[x_2] \le \cdots \le \texttt{dist}[x_k] \le \texttt{dist}[x_1] + 1. \]
\(I\) holds at the first test of the loop. Then \(Q\) holds only \(s\), and \(\texttt{dist}[s] \le \texttt{dist}[s] + 1\).
\(I\) is a loop invariant. Suppose \(I\) holds at a test, and the pass removes \(v = x_1\). The vertices \(x_2, \ldots, x_k\) that remain have labels in nondecreasing order, each from \(\texttt{dist}[v]\) to \(\texttt{dist}[v] + 1\). Every vertex the pass adds goes to the back, with the label \(\texttt{dist}[v] + 1\), which is at least every label before it. So the labels in \(Q\) are still in nondecreasing order. Each of them is at most \(\texttt{dist}[v] + 1\), and the new first label is at least \(\texttt{dist}[v]\), so the last label is at most the new first label plus 1. So \(I\) holds at the next test, and \(I\) is a loop invariant, by Theorem: The loop invariant theorem.
The labels never decrease. Suppose a pass removes \(v\), and the next pass removes \(w\). At the test between them, \(I\) holds, and \(w\) is at the front of \(Q\). Every label in \(Q\) at that test is either the label of a vertex that was behind \(v\), which is at least \(\texttt{dist}[v]\) by \(I\) before the pass, or \(\texttt{dist}[v] + 1\). So \(\texttt{dist}[w] \ge \texttt{dist}[v]\).
Proof. Let \(T\) and \(r\) be as in Definition 18. For each vertex \(v\), a walk (Definition: Walk) from \(r\) to \(v\) of the smallest length is a path (Theorem: A shortest walk is a path), and the only path from \(r\) to \(v\) (Theorem 1) has length \(\operatorname{level}(v)\), so \(\operatorname{dist}(r, v) = \operatorname{level}(v)\) (Definition: Distance). Since \(T\) is connected, Theorem: Breadth-first search finds distances says that bfs(T, r) marks every vertex \(v\), with \(\texttt{dist}[v] = \operatorname{dist}(r, v) = \operatorname{level}(v)\). By Lemma 4, the vertices leave the queue with their labels \(\texttt{dist}\) in nondecreasing order. So the levels of the vertices in the level order never decrease, and every vertex at level \(k\) comes before every vertex at level \(k + 1\).
7 Binary trees in Racket
8 Expression trees
9 Spanning trees
Proof. A graph with a spanning tree is connected. Let \(S\) be a spanning tree of \(G\), and let \(u\) and \(v\) be vertices of \(G\). They are vertices of \(S\), which is connected, so there is a walk from \(u\) to \(v\) in \(S\), and it is also a walk in \(G\).
A connected graph has a spanning tree. We use strong induction (Definition: Proof by strong induction) on the number \(m \ge 0\) of edges, proving that every connected graph with \(m\) edges has a spanning tree. Let \(G\) be a connected graph with \(m\) edges, and suppose that every connected graph with fewer than \(m\) edges has a spanning tree.
If \(G\) has no cycles (Definition: Cycle), it is a tree, and it is a spanning tree of itself.
Otherwise, let \(v_0, e_1, v_1, \ldots, e_n, v_n\) be a cycle of \(G\), with \(v_n = v_0\), and let \(H\) be the subgraph (Definition: Subgraph) of \(G\) with all the vertices of \(G\) and all its edges but \(e_1\). \(H\) is connected. Take a walk in \(G\) between two vertices, and change each step along \(e_1\):
- if \(n = 1\), then \(e_1\) is a loop at \(v_0\), and the step \(v_0, e_1, v_0\) can be left out;
- if \(n \ge 2\), then \(e_1\) joins \(v_0\) and \(v_1\), and the walk \(v_1, e_2, v_2, \ldots, e_n, v_0\) goes from \(v_1\) to \(v_0\) without \(e_1\), since the edges of a cycle are all different; a step along \(e_1\) from \(v_1\) to \(v_0\) can be replaced by it, and a step from \(v_0\) to \(v_1\) by it read backward.
The result is a walk in \(H\) between the same two vertices. \(H\) has \(m - 1\) edges, so by the induction hypothesis it has a spanning tree. That tree is a subgraph of \(G\) with every vertex of \(G\), so it is a spanning tree of \(G\).
By strong induction, every connected graph has a spanning tree.
Proof. By Theorem 6, \(G\) has a spanning tree \(S = (V, E_S)\), which has \(n - 1\) edges by Theorem 2. Since \(E_S \subseteq E\), \({\mathopen{}\left|E\right|\mathclose{}} \ge {\mathopen{}\left|E_S\right|\mathclose{}} = n - 1\). If \({\mathopen{}\left|E\right|\mathclose{}} = n - 1\), then \(E_S\) is a subset of \(E\) with as many elements as \(E\), so \(E_S = E\), and \(G = S\) is a tree.
Proof. Let \(S\) be the breadth-first search tree, let \(n\) be the number of vertices of \(G\), and for each vertex \(u \ne s\) let \(v(u)\) be the vertex whose removal marks \(u\), so that \({\mathopen{}\left\{v(u), u\right\}\mathclose{}}\) is the edge of \(S\) for \(u\). Since \(v(u)\) was marked before \(u\), \(v(u) \ne u\).
\(S\) has \(n - 1\) edges. There is one edge for each of the \(n - 1\) vertices \(u \ne s\). Suppose, for contradiction (Definition: Proof by contradiction), that two vertices \(u \ne w\) give the same edge. Then \(w = v(u)\) and \(u = v(w)\), so \(w\) was marked before \(u\) and \(u\) was marked before \(w\), which is impossible. So these \(n - 1\) edges are all different.
\(S\) is connected, and each level is the distance. We show, by strong induction (Definition: Proof by strong induction) on the order in which the vertices are marked, that for each vertex \(u\) there is a path (Definition: Path) in \(S\) from \(s\) to \(u\) of length \(\texttt{dist}[u]\), whose vertices were marked in the order of the path. For \(s\), the path \(s\) has length \(0 = \texttt{dist}[s]\). For \(u \ne s\), the vertex \(v(u)\) was marked earlier, so there is such a path from \(s\) to \(v(u)\) of length \(\texttt{dist}[v(u)]\). All its vertices were marked no later than \(v(u)\), so before \(u\), and following it with the edge \({\mathopen{}\left\{v(u), u\right\}\mathclose{}}\) gives a path from \(s\) to \(u\), of length \(\texttt{dist}[v(u)] + 1 = \texttt{dist}[u]\) (Definition: Breadth-first search).
So \(S\) has a walk from \(s\) to every vertex, and two of these walks, one read backward, join any two vertices. \(S\) is connected with \(n\) vertices and \(n - 1\) edges, so it is a tree by Corollary 1. With root \(s\), the path just built is the only path from \(s\) to \(u\) (Theorem 1), so \(\operatorname{level}(u) = \texttt{dist}[u] = \operatorname{dist}(s, u)\), by Theorem: Breadth-first search finds distances.
Proof. At most one call. Apart from the first call, a call dfs(G, u) is made only when \(u\) is not marked, and every call dfs(G, u) marks \(u\) before it makes any other call. Marks are never removed, so after the first call on \(u\), \(u\) stays marked, and no later call on \(u\) is made.
At least one call. Since \(G\) is connected, there is a walk (Definition: Walk) from \(s\) to every vertex, so Theorem: Depth-first search finds what can be reached says that dfs(G, s) marks every vertex. A vertex is marked only by a call on it, so there is a call on every vertex.
Who makes the call. For \(u \ne s\), the call on \(u\) is not the first call, so it is made by a call dfs(G, v) while it goes through the list of \(v\), and \(u\) is in that list, so \(u\) is adjacent to \(v\).
Proof. Let \(S\) be the depth-first search tree, let \(n\) be the number of vertices of \(G\), and for each vertex \(u \ne s\) let \(v(u)\) be the vertex whose call makes the call dfs(G, u). The call on \(v(u)\) starts before the call on \(u\), so \(v(u) \ne u\).
\(S\) has \(n - 1\) edges. There is one edge \({\mathopen{}\left\{v(u), u\right\}\mathclose{}}\) for each of the \(n - 1\) vertices \(u \ne s\). If two vertices \(u \ne w\) gave the same edge, then \(w = v(u)\) and \(u = v(w)\), so the call on \(w\) started before the call on \(u\), and the call on \(u\) started before the call on \(w\), which is impossible.
\(S\) is connected. By strong induction (Definition: Proof by strong induction) on the order in which the calls start, there is a walk in \(S\) from \(s\) to each vertex \(u\): for \(u = s\) the walk \(s\), and for \(u \ne s\) a walk from \(s\) to \(v(u)\), whose call started earlier, followed by the edge \({\mathopen{}\left\{v(u), u\right\}\mathclose{}}\). Two of these walks, one read backward, join any two vertices.
\(S\) is connected with \(n\) vertices and \(n - 1\) edges, so it is a tree by Corollary 1, and it has every vertex of \(G\).











