Trees, Binary Search Trees, Heaps and Graph Representations
Heaps in an Array, and Why Building One Is Linear
| Quantity | Value | For n = 100 |
|---|---|---|
| Leaves | ⌈n/2⌉ — the last half | 50 |
| Internal nodes | ⌊n/2⌋ — the first half | 50 |
| Height | ⌊log₂n⌋ | 6 |
| Build from an unsorted array | O(n) | Not O(n log n) |
| n successive inserts | O(n log n) | A different operation |
One more heap fact is asked often enough to be worth stating: the minimum of a max-heap must be a leaf, because any internal node is greater than its children. So finding it requires inspecting all ⌈n/2⌉ leaves — 50 comparisons for a 100-element heap — and there is no shortcut, which is the price a heap pays for being a partial rather than a total order.
Two Ways to Store a Graph
| Operation | Matrix | List |
|---|---|---|
| Space | O(V²) always | O(V + E) |
| Is there an edge (u, v)? | O(1) | O(degree of u) |
| Enumerate all neighbours of u | O(V) | O(degree of u) |
| Add an edge | O(1) | O(1) at the head |
| Suits | Dense graphs, E ≈ V² | Sparse graphs, E ≪ V² |
The choice is decided by density, and the crossover is not subtle: a graph with a million vertices and two million edges needs about three million list entries and would need a million million matrix cells. That is why every practical graph algorithm is written against adjacency lists, and why a traversal is quoted as O(V + E) rather than O(V²) — the bound is a statement about the representation as much as about the algorithm.
Key takeaways
- Fix the height convention first: counted in edges, a single node has height 0.
- A binary tree of height h has at most 2h+1 − 1 nodes and at least h + 1.
- In every binary tree n₀ = n₂ + 1 — leaves are one more than two-child nodes, whatever the shape.
- Distinct BSTs on n distinct keys is the nth Catalan number: 5, 14, 42 for n = 3, 4, 5.
- Preorder plus inorder fixes a tree; preorder plus postorder does not, except for a full binary tree.
- In an array heap of n, leaves are the last ⌈n/2⌉ and internal nodes the first ⌊n/2⌋.
- Heapify is O(n); inserting n elements one by one is O(n log n) — two different operations.
- The minimum of a max-heap is a leaf, so finding it costs ⌈n/2⌉ comparisons.
- Matrix: O(V²) space, O(1) edge test. List: O(V + E) space, O(degree) edge test.
Practice questions (8)
Attempt each one before opening the answer. Every explanation names the tempting wrong option as well as the right one, because that is where marks are lost.
How many distinct binary search trees can be formed from 5 distinct keys?
Numerical answer — type the value.
Show answer
Answer: 42
The count is the fifth Catalan number, 42. The recurrence is the reason: choose any key as the root, and if i keys fall to its left then Cᵢ × C₄₋ᵢ trees follow, summed over all five choices of root. The sequence runs 1, 2, 5, 14, 42, 132. Note that this also counts the distinct shapes of a 5-node binary tree — the same 42 — because once a shape is fixed, the BST property determines which key goes where, with no freedom left. The count of labelled binary trees is a different question: 42 × 5! = 5040, and a question saying "labelled" is asking for that instead.A binary tree has 20 leaves. How many of its nodes have exactly two children?
Numerical answer — type the value.
Show answer
Answer: 19
n₀ = n₂ + 1 in every binary tree, so n₂ = 20 − 1 = 19. The relation comes from counting edges twice: a tree with n nodes has n − 1 edges, and the edges also total n₁ + 2n₂, and eliminating n gives the result with n₁ vanishing. That vanishing is why the answer needs no information about the shape or about how many nodes have one child — a fact worth trusting, because the question deliberately withholds both. Total node count is not determined: any n₁ ≥ 0 is consistent with 20 leaves.Building a binary heap from an unsorted array of n elements using the standard bottom-up heapify takes:
Show answer
Answer: B — O(n)
O(n). The loose analysis multiplies n nodes by O(log n) per sift and reaches O(n log n), but that overcounts badly: half the nodes are leaves and sift nothing, a quarter sift at most one level, an eighth at most two. Summing (n/2k+1) × k over the levels converges to about 2n. Option A is the right answer to a different operation — inserting the n elements one at a time, where each new element sifts up from a leaf and the deep positions are the common case, giving a genuine O(n log n). Both build a heap and they differ by a log factor, so the wording of the question decides the answer.A max-heap holds 100 elements in an array. In the worst case, how many elements must be examined to find the minimum?
Numerical answer — type the value.
Show answer
Answer: 50
The minimum of a max-heap must be a leaf, since every internal node exceeds its children. In an array heap of n the leaves are the last ⌈n/2⌉ positions, so for n = 100 there are 50 of them and all must be compared — there is no ordering among leaves to exploit. This is the cost of a heap being a partial order: it gives O(1) access to the maximum and nothing at all at the other end, which is why a structure needing both ends uses two heaps or a different design entirely. Answering 1 or log n treats the heap as if it were sorted, which it is not.Which pair of traversals always determines a binary tree uniquely?
Show answer
Answer: B — Preorder and inorder
Preorder and inorder. Preorder names the root; inorder says how many keys lie to its left, which splits the remaining sequence into the two subtrees, and the argument recurses. Inorder is the only traversal carrying that split information, which is why every working pair includes it — postorder and inorder work too. Preorder and postorder do not: a root with only a left child and the same root with only a right child produce identical sequences in both, so two distinct trees share them. The exception is a full binary tree, where no node has exactly one child and the ambiguity cannot arise — a question adding the word "full" is switching the answer to A.Which of the following are true of an adjacency list compared with an adjacency matrix? (More than one may be correct.)
Show answer
Answer: A — It uses O(V + E) space rather than O(V²); B — Testing whether a specific edge exists is slower; C — Enumerating a vertex’s neighbours is faster for a sparse graph
A, B and C, which together are the whole trade. The list stores only edges that exist, so space is O(V + E) (A) and walking one vertex's neighbours costs O(degree) rather than scanning a whole row of V cells (C). The price is that answering "is (u, v) an edge?" means searching u's list, O(degree), where the matrix answers in O(1) (B). D is false — a directed graph is if anything more natural in a list, since the edge is simply stored once, in u's list only. The decision between them is density: a graph with a million vertices and two million edges is unrepresentable as a matrix and unremarkable as a list.With height counted in edges, the maximum number of nodes in a binary tree of height 4 is:
Show answer
Answer: B — 31
Levels 0 through 4 hold at most 1, 2, 4, 8 and 16 nodes, totalling 2⁵ − 1 = 31. The formula is 2h+1 − 1 with height in edges. Option A is the answer for height 3, and it is what you get from the same formula under the other convention, where height counts nodes and a single node has height 1 — which is exactly why the convention has to be stated before the question can be answered. Option D drops the −1, forgetting that a full level of 16 sits on top of 15 already there.In the worst case, searching a binary search tree with n nodes takes:
Show answer
Answer: B — O(n), because the tree may degenerate into a path
A BST search costs O(h), and h can be anything from ⌊log₂n⌋ up to n − 1: inserting keys in sorted order produces a tree that is one long path, and searching it is a linear scan with pointer-chasing overhead. So the worst case is O(n). Option A is the balanced case and is what the structure is usually sold on, which is why the distinction matters — and it is exactly the gap that AVL and red-black trees exist to close, by enforcing O(log n) height at the cost of rebalancing work on every insert. A question saying "balanced" or "AVL" is asking for O(log n); a plain BST is not entitled to it.