Unit 1 · Algorithms · Lesson 12 of 24
Trees and binary search trees
Builds on
Step 1: Learn the ideas
- Terminology: depth, height, complete and balanced trees
- Depth-first traversals: pre-order, in-order, post-order
- Breadth-first traversal and level processing
- Returned subtree summaries versus recorded global answers
- Lowest common ancestor in binary trees and BSTs
- BST invariant, search, insertion and deletion
- In-order traversal and BST iterators
- Balanced BSTs: AVL and red-black rotations
- Augmented trees: subtree sizes for rank and select
- Serialization and reconstruction from traversals
Why it matters
Trees are recursive by construction, which makes them a natural place to practice "solve the children, then combine". They also model real systems: file systems, DOM trees, syntax trees, and the ordered indexes behind databases and library maps. Interviewers use tree problems to check recursion fluency, the choice between depth-first and breadth-first traversal, and whether you respect an invariant such as BST ordering.
Core ideas
Pattern: Tree DFS / recursion on subtrees. Most tree problems are a post-order computation: get a result from each subtree and combine it at the node. Write the contract precisely, including the empty tree. For Diameter of Binary Tree the function returns the height of its subtree and, along the way, updates a global best with left_height + right_height. The returned value (one downward branch) and the recorded value (a path through the node) are different quantities, which is the key idea in Diameter and in Binary Tree Maximum Path Sum. Lowest Common Ancestor has the same shape: each call reports whether its subtree contains p or q, and the answer is the deepest node whose subtree, counting the node itself, contains both.
Traversal orders. Pre-order (node, left, right) copies or serializes structure; in-order (left, node, right) visits a BST in sorted order; post-order (left, right, node) computes results bottom-up. Iterative versions use an explicit stack, which avoids recursion limits on degenerate trees whose depth is n.
Pattern: Tree BFS / level order. A queue processes nodes by depth. To handle one level at a time, read the queue's length at the start of the level and pop exactly that many nodes. Right-side views, level averages, zigzag order and minimum depth are small changes to this loop.
Pattern: BST ordering invariant. Every key in a node's left subtree is smaller than the node's key, and every key in its right subtree is larger. This constrains whole subtrees, not just children, so validate it by passing an allowed interval (low, high) down the recursion, tightening high when going left and low when going right. Consequences:
- Search and insertion follow one root-to-leaf path: O(h) for height h.
- In-order traversal yields sorted keys, so the k-th smallest key is the k-th node visited; an iterator with an explicit stack uses O(h) memory and amortized O(1) per step.
- Deletion has three cases: a leaf is removed, a node with one child is spliced out, and a node with two children takes the key of its in-order successor (the leftmost node of its right subtree), which is then deleted.
- LCA in a BST walks down from the root: go left while both keys are smaller, right while both are larger, and stop otherwise.
Height and balance. Every BST bound is O(h), and inserting sorted keys into a plain BST produces a path with h = n. Self-balancing trees keep h = O(log n) with rotations: AVL trees bound the height difference between siblings, red-black trees enforce coloring rules. You rarely implement them in an interview, but you should explain why they exist and reach for the library ordered map (C++ std::map, Java TreeMap) when you need floor or ceiling queries. Storing subtree sizes in nodes supports rank and select in O(h).
Reconstruction. Pre-order plus in-order traversals determine a tree with distinct keys: the first pre-order element is the root, and its position in the in-order sequence splits left from right; an index map makes this O(n). Serialization needs explicit null markers to be unambiguous.
Common misconceptions
- "Check that each node lies between its children." The invariant concerns whole subtrees; a node deep in the left subtree can violate the root's bound.
- "BST operations are O(log n)." They are O(h); only balanced trees guarantee O(log n).
- "Tree recursion uses O(log n) stack." Only for balanced trees; a skewed tree needs O(n).
- "Return the global answer from every call." The value a call returns and the answer it records are often different.
- "BFS and DFS are interchangeable." BFS reaches the shallowest nodes first and organizes work by level; DFS suits subtree summaries and uses memory proportional to height rather than width.
How to approach it
State the function's contract and its value for an empty subtree before coding. Decide whether the question is about levels (BFS) or subtree summaries (DFS). For BSTs, name the invariant and use it to prune. Test an empty tree, a single node and a skewed tree. Interviewers typically probe the difference between returned and recorded values, BST validation and complexity on unbalanced input; deeper discussions cover balancing and when an ordered map from the standard library is the right tool. Aim to recognize these shapes in unseen problems rather than recall solutions to specific ones.
Suggested order
- 1Read MIT 6.006 Lecture 6 (Binary Trees, Part 1) and Recitation 6 for traversal order, successor and predecessor, and dynamic operations.
- 2Read MIT 6.006 Lecture 7 (Binary Trees, Part 2: AVL) for rotations, height balance and subtree augmentation; aim to explain it rather than implement it.
- 3Solve Maximum Depth of Binary Tree and Diameter of Binary Tree, writing each function’s contract first.
- 4Solve Binary Tree Level Order Traversal with the per-level queue loop.
- 5Solve Validate Binary Search Tree with bounds, then Kth Smallest Element in a BST with an iterative in-order traversal.
- 6Read the algs4 Binary Search Trees section (3.2) for Hibbard deletion, then solve Delete Node in a BST.
- 7Solve Lowest Common Ancestor of a Binary Tree and Construct Binary Tree from Preorder and Inorder Traversal.
- 8Review with Binary Tree Maximum Path Sum and Serialize and Deserialize Binary Tree.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
MIT 6.006 Introduction to Algorithms (Spring 2020)Start here
MIT OpenCourseWareSection: Lecture 6: Binary Trees, Part 1
Traversal order, subtree navigation, insertion and deletion, and binary trees used as sets and sequences.
Open(opens in a new tab)Link responded, 5 Oct 2026MIT 6.006 Introduction to Algorithms (Spring 2020)
MIT OpenCourseWareSection: Lecture 7: Binary Trees, Part 2: AVL
Rotations, AVL height balance and subtree augmentation for order statistics.
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms, 4th Edition booksite: sorting, searching and trie sections
Princeton UniversitySection: 3.2 Binary Search Trees
BST code with floor, ceiling, rank, select and Hibbard deletion, plus the analysis of height for random insertion orders.
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms, 4th Edition booksite: sorting, searching and trie sections
Princeton UniversitySection: 3.3 Balanced Search Trees
2-3 trees and left-leaning red-black trees, for deep-level understanding of balancing.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Write each function’s contract (what it returns for a subtree, including the empty tree) before coding, and say whether you also record a separate global answer. Use BFS only when the question is about levels or the shallowest node. Delete Node in a BST checks the two-child case; Binary Tree Maximum Path Sum and Serialize and Deserialize Binary Tree are review problems for the returned-versus-recorded distinction and for unambiguous encodings.
- Maximum Depth of Binary TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Diameter of Binary TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Binary Tree Level Order TraversalLeetCode(opens in a new tab)Not attemptedLeetCode
- Validate Binary Search TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Kth Smallest Element in a BSTLeetCode(opens in a new tab)Not attemptedLeetCode
- Delete Node in a BSTLeetCode(opens in a new tab)Not attemptedLeetCode
- Lowest Common Ancestor of a Binary TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Construct Binary Tree from Preorder and Inorder TraversalLeetCode(opens in a new tab)Not attemptedLeetCode
- Binary Tree Maximum Path SumLeetCode(opens in a new tab)Not attemptedLeetCode
- Serialize and Deserialize Binary TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Binary Tree Right Side ViewLeetCode(opens in a new tab)Not attemptedLeetCode
- Invert Binary TreeLeetCode(opens in a new tab)Not attemptedLeetCode
- Lowest Common Ancestor of a Binary Search TreeLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1What does your recursive function return for an empty subtree, and why?
- Question 2Why is comparing each node with its children insufficient for BST validation?
- Question 3In Diameter of Binary Tree, what is returned and what is recorded?
- Question 4What are the three BST deletion cases, and why does the in-order successor preserve the invariant?
- Question 5When would you choose BFS over DFS for a tree problem?
- Question 6What is the recursion depth of a traversal on a skewed tree?
You’re done when you can
- Solve two unseen tree problems in under 20 minutes each, stating the recursive contract before coding.
- Validate a BST and delete a node with two children correctly on the first attempt.
- Write an iterative in-order traversal with an explicit stack from memory.
- Explain in two minutes why plain BST operations can degrade to O(n) and how balanced trees prevent it.
Finish the lesson
Unlocks next: Tries (prefix trees), Pattern recognition and mixed practice


