Binary Trees and Traversals

Tree terminology, the four classic traversals, height and counting nodes.

A tree is a hierarchy of nodes. The top node is the root; every other node has exactly one parent. Nodes without children are leaves. In a binary tree every node has at most two children, called left and right.

ArootBDleafEleafCFleaf
The binary tree used in this lesson
TermMeaning (for the tree above)
Depth of a nodenumber of edges from the root (depth of E is 2)
Height of the treenumber of edges on the longest root-to-leaf path (2)
Degree of a nodenumber of children (B has 2, C has 1)
Internal nodea node with at least one child (A, B, C)

Special binary trees

  • Full (proper): every node has 0 or 2 children.
  • Complete: every level is full except possibly the last, which is filled from the left. Heaps are complete trees.
  • Perfect: all internal nodes have 2 children and all leaves are at the same depth. A perfect tree of height h has 2^(h+1) − 1 nodes.

The four traversals

A traversal visits every node once. The depth-first traversals differ only in when the node itself is visited relative to its subtrees:

TraversalOrderResult for the tree above
Preordernode, left, rightA B D E C F
Inorderleft, node, rightD B E A F C
Postorderleft, right, nodeD E B F C A
Level order (breadth-first)level by level, left to rightA B C D E F
import java.util.ArrayDeque;
import java.util.Queue;

public class Main {
    static class Node {
        char val;
        Node left, right;
        Node(char val, Node left, Node right) { this.val = val; this.left = left; this.right = right; }
        Node(char val) { this(val, null, null); }
    }

    static void preorder(Node n, StringBuilder out) {
        if (n == null) return;
        out.append(n.val).append(' ');
        preorder(n.left, out);
        preorder(n.right, out);
    }

    static void inorder(Node n, StringBuilder out) {
        if (n == null) return;
        inorder(n.left, out);
        out.append(n.val).append(' ');
        inorder(n.right, out);
    }

    static void postorder(Node n, StringBuilder out) {
        if (n == null) return;
        postorder(n.left, out);
        postorder(n.right, out);
        out.append(n.val).append(' ');
    }

    static String levelOrder(Node root) {
        StringBuilder out = new StringBuilder();
        Queue<Node> q = new ArrayDeque<>();
        q.add(root);
        while (!q.isEmpty()) {
            Node n = q.poll();
            out.append(n.val).append(' ');
            if (n.left != null) q.add(n.left);
            if (n.right != null) q.add(n.right);
        }
        return out.toString().trim();
    }

    static int height(Node n) { return n == null ? -1 : 1 + Math.max(height(n.left), height(n.right)); }
    static int count(Node n) { return n == null ? 0 : 1 + count(n.left) + count(n.right); }
    static int leaves(Node n) {
        if (n == null) return 0;
        if (n.left == null && n.right == null) return 1;
        return leaves(n.left) + leaves(n.right);
    }

    public static void main(String[] args) {
        Node root = new Node('A',
            new Node('B', new Node('D'), new Node('E')),
            new Node('C', new Node('F'), null));

        StringBuilder pre = new StringBuilder(), in = new StringBuilder(), post = new StringBuilder();
        preorder(root, pre);
        inorder(root, in);
        postorder(root, post);
        System.out.println("preorder:   " + pre.toString().trim());
        System.out.println("inorder:    " + in.toString().trim());
        System.out.println("postorder:  " + post.toString().trim());
        System.out.println("levelorder: " + levelOrder(root));
        System.out.println("height=" + height(root) + " nodes=" + count(root) + " leaves=" + leaves(root));
    }
}
Output
preorder:   A B D E C F
inorder:    D B E A F C
postorder:  D E B F C A
levelorder: A B C D E F
height=2 nodes=6 leaves=3

Each traversal visits every node once, so it takes Θ(n) time. The recursive versions use O(h) stack space, where h is the height.

Rebuilding a tree from traversals

Preorder (or postorder) together with inorder identifies a binary tree uniquely: the first preorder item is the root, and its position in the inorder sequence splits the remaining nodes into left and right subtrees. Preorder with postorder alone is not enough in general.

Useful counting facts

  • A binary tree of height h has at most 2^(h+1) − 1 nodes, so a tree with n nodes has height at least ⌈log₂(n+1)⌉ − 1.
  • In any binary tree, the number of leaves = (number of nodes with two children) + 1.
  • The number of structurally different binary trees with n nodes is the Catalan number C(2n, n) / (n + 1): 1, 2, 5, 14, 42, ...

GATE-style practice questions

GATE-styleMCQ · one correct answer

The preorder traversal of a binary tree is P Q S T R U and its inorder traversal is S Q T P U R. What is its postorder traversal?

Show answer and explanationAnswer: B

P is the root (first in preorder). In inorder, S Q T is the left subtree and U R the right. In the left part Q is the root (next in preorder) with children S and T. In the right part R is the root with left child U. Postorder: S T Q, then U R, then P.

GATE-styleNAT · numerical answer

A binary tree has 20 nodes with two children each. How many leaves does it have?

Show answer and explanationAnswer: 21

In every binary tree, leaves = nodes with two children + 1. Count edges two ways: n − 1 edges, and also 2·n₂ + 1·n₁ edges, with n = n₀ + n₁ + n₂. Solving gives n₀ = n₂ + 1 = 21.

GATE-styleNAT · numerical answer

How many structurally different binary trees can be formed with 4 nodes?

Show answer and explanationAnswer: 14

The count is the 4th Catalan number C(2n, n) / (n + 1) = C(8, 4) / 5 = 70 / 5 = 14.

GATE-styleNAT · numerical answer

What is the maximum number of nodes in a binary tree of height 5? (A single node has height 0.)

Show answer and explanationAnswer: 63

Level d holds at most 2^d nodes, so a tree of height h has at most 1 + 2 + ... + 2^h = 2^(h+1) − 1 = 63 nodes.