3.4.10 · D4Trees

Exercises — Heap — max-heap and min-heap properties

2,690 words12 min readBack to topic

Reminders you will reuse constantly (0-based arrays of size ):


Level 1 — Recognition

L1.1 — Valid max-heap?

State whether [10, 8, 9, 4, 7, 5, 3] is a valid max-heap. Justify per internal node.

Recall Solution

Size . Internal nodes: indices with , i.e. . Leaves: .

  • (val 10): children at 1 (=8), 2 (=9). ✓, ✓.
  • (val 8): children at 3 (=4), 4 (=7). ✓, ✓.
  • (val 9): children at 5 (=5), 6 (=3). ✓, ✓. Every parent dominates both children → valid max-heap. (Note child 8 at index 1 is smaller than sibling-subtree value 9 — siblings are unordered, that's allowed.)

L1.2 — Valid min-heap?

Is [1, 3, 2, 6, 5, 9, 8] a valid min-heap?

Recall Solution

, internal nodes .

  • (1): children 3, 2 → ✓, ✓.
  • (3): children 6, 5 → ✓, ✓.
  • (2): children 9, 8 → ✓, ✓. Valid min-heap.

L1.3 — Spot the violation

Find every parent–child pair that breaks the max-heap rule in [9, 12, 8, 3, 4].

Recall Solution

, internal nodes .

  • (9): children 12 (idx 1), 8 (idx 2). ? No → violation (9,12). ✓.
  • (12): children 3 (idx 3), 4 (idx 4). ✓, ✓. One violating pair: root 9 vs left child 12.

Level 2 — Application

L2.1 — One max-heapify (sift-down) step

Run sift-down on the root of [4, 10, 9, 2, 8, 7] until it is a valid max-heap. Show each swap.

Recall Solution

. Push the too-small root toward the leaves.

  • (4): children 10 (idx1), 9 (idx2). Larger child = 10. → swap. [10, 4, 9, 2, 8, 7].
  • Follow the 4 to : children 2 (idx3), 8 (idx4). Larger = 8. → swap. [10, 8, 9, 2, 4, 7].
  • Follow to : → leaf, stop. Result [10, 8, 9, 2, 4, 7]. We swapped with the larger child each time so the new parent dominates the other child automatically.

L2.2 — Insert + sift-up (max-heap)

Insert 15 into max-heap [14, 10, 12, 5, 8, 11], then restore order.

Recall Solution

Append at the next free leaf to keep the shape complete: [14, 10, 12, 5, 8, 11, 15], new index 6.

  • (val 12). Max rule: parent ≥ child? ? No → swap. [14, 10, 15, 5, 8, 11, 12]. Now the 15 is at index 2.
  • (val 14). ? No → swap. [15, 10, 14, 5, 8, 11, 12]. At index 0 → root, stop. Result [15, 10, 14, 5, 8, 11, 12] — 15 bubbled to the top.

L2.3 — Extract-max

Extract the maximum from [15, 10, 14, 5, 8, 11, 12] (the result of L2.2). Show the standard extract procedure.

Recall Solution

Standard extract-max: (1) save root, (2) move last element to root, (3) shrink, (4) sift-down.

  • Save 15. Last element = 12 → root. Shrink: [12, 10, 14, 5, 8, 11], .
  • Sift-down from (12): children 10 (idx1), 14 (idx2). Larger = 14. → swap. [14, 10, 12, 5, 8, 11].
  • Follow 12 to : children 11 (idx5). . Larger child = 11. ✓ → stop. Returned max = 15, remaining heap [14, 10, 12, 5, 8, 11] (valid).

Level 3 — Analysis

L3.1 — Where can the minimum live in a max-heap?

In a max-heap of nodes (), which array indices could hold the minimum value? Explain why.

Recall Solution

The minimum must be a leaf. Reason: if the minimum sat at an internal node, it would have a child, and every child is its parent in... no — in a max-heap children are parent. So an internal node's children are all it, meaning some descendant is the node — the node can't be the unique smallest unless it has no children. Formally: any internal node has a child itself, so a strictly-smaller value exists below it, so an internal node cannot be the minimum. Hence the minimum lives among the leaves. Leaves are the indices with , i.e. indices . The minimum can be at any leaf index, roughly the last half of the array.

L3.2 — Fastest peek at second-largest

In a max-heap, without doing a full search, where must the second largest element be, and how fast can you find it?

Recall Solution

The largest is at the root (index 0). The second largest must be a child of the root — index 1 or index 2. Why? Any element that is not the root has a parent . If were second-largest but not a root-child, its parent would be some non-root node, and that parent is and root, giving a third value between and the max — contradiction with being second. So second-largest sits at index 1 or 2. Cost: compare and , take the larger → .

L3.3 — Counting leaves

A heap stored in a 0-based array of size . How many leaves does it have, expressed with a floor?

Recall Solution

A node is internal iff it has a left child, i.e. . So internal indices are , giving internal nodes. The rest are leaves: For : leaves (indices 3,4,5,6) — matches L1.1.


Level 4 — Synthesis

L4.1 — Build-heap by bottom-up heapify

Turn the raw array [3, 1, 6, 5, 2, 4] into a max-heap using bottom-up build-heap (call sift-down on each internal node from the last one down to the root). Show the array after each node.

Recall Solution

. Internal nodes: (since ). Process highest index first: .

  • (val 6): child 4 (idx5). ✓ → no change. [3, 1, 6, 5, 2, 4].
  • (val 1): children 5 (idx3), 2 (idx4). Larger = 5. → swap. [3, 5, 6, 1, 2, 4]. Follow 1 to idx3 → leaf (), stop.
  • (val 3): children 5 (idx1), 6 (idx2). Larger = 6. → swap. [6, 5, 3, 1, 2, 4]. Follow 3 to idx2: child 4 (idx5). ? No → swap. [6, 5, 4, 1, 2, 3]. Follow 3 to idx5 → leaf, stop. Result [6, 5, 4, 1, 2, 3] — verify: root 6 ≥ {5,4} ✓; 5 ≥ {1,2} ✓; 4 ≥ {3} ✓. Valid max-heap.

Referenced by Build-Heap (Heapify) O(n): doing it bottom-up costs , not .

L4.2 — Heapsort trace (one pass idea)

Given the max-heap [6, 5, 4, 1, 2, 3] from L4.1, perform the first two extract-max steps of heapsort (swap root with last, shrink heap region, sift-down). Track the sorted tail.

Recall Solution

Heapsort keeps a "heap region" at the front and a growing sorted tail at the back.

  • Step 1: swap root (6) with last (3): [3, 5, 4, 1, 2, | 6]. Heap region size 5. Sift-down idx0 (3): children 5,4 → larger 5, swap. [5, 3, 4, 1, 2, |6]. Follow to idx1 (3): children 1,2 → larger 2, ✓ stop. Sorted tail: [6].
  • Step 2: swap root (5) with last-of-region (2, idx4): [2, 3, 4, 1, | 5, 6]. Heap size 4. Sift-down idx0 (2): children 3 (idx1), 4 (idx2) → larger 4, swap. [4, 3, 2, 1, |5, 6]. Follow to idx2 (2): ≥ heap size 4 → leaf, stop. Sorted tail: [5, 6]. After two extracts: array [4, 3, 2, 1, 5, 6], the last two positions 5,6 are the final sorted values. Continuing would produce [1,2,3,4,5,6]. See Heapsort.

Level 5 — Mastery

L5.1 — Is the array [7, 6, 5, 4, 3, 2, 1] always a valid max-heap? Prove or disprove for general sorted-descending arrays.

Claim to test: a descending-sorted array is always a valid max-heap.

Recall Solution

True — prove it. For a descending array, . For any node its children are at and , both . Since the array is non-increasing, and whenever those indices exist. That is exactly the max-heap order property for every node. Hence any descending-sorted array is a valid max-heap. (The converse is false: [6,5,4,1,2,3] from L4.1 is a valid max-heap but not sorted.) Test case [7,6,5,4,3,2,1]: root 7 ≥ {6,5}; 6 ≥ {4,3}; 5 ≥ {2,1} → valid.

L5.2 — Merge cost lower bound reasoning

You have two separate max-heaps of sizes and stored as arrays. A friend claims you can merge them into one valid max-heap in time. Argue whether that is possible.

Recall Solution

Not possible in general with the simple array heap. To merge, you must produce a single complete tree over all elements obeying heap order. Even just placing every element into the combined array touches slots, and running build-heap on the concatenation costs (from Build-Heap (Heapify) O(n)). Since for large inputs, merge is impossible for binary array heaps. (Specialised structures — binomial/pairing heaps — achieve merge, but not the plain complete-binary-tree array heap of this note.) Verdict: the claim is false for array heaps.

L5.3 — Minimum comparisons to confirm a max-heap

For an array of size , what is the number of comparisons needed to verify the max-heap order property in the worst case? Give an exact expression.

Recall Solution

Every internal node is compared against each existing child. A node with two children costs 2 comparisons; a node with one child costs 1. In a complete tree exactly one node may have a single child (the parent of the very last leaf, when is even). Let be the number of internal nodes (from L3.3).

  • If is odd: every internal node has two children → comparisons.
  • If is even: one internal node has a single child → comparisons. In both cases the total is exactly comparisons. For : comparisons.

Recall

Recall Quick self-test (cover answers)

Where can the minimum of a max-heap be? ::: At any leaf (indices ). Second-largest in a max-heap lives where? ::: At index 1 or 2 (a child of the root); to find. Number of leaves of an -node heap? ::: . Number of internal nodes? ::: . Comparisons to verify max-heap order? ::: exactly . Build-heap direction and why? ::: Bottom-up, so sift-down always sits above valid sub-heaps. In sift-down of a max-heap, swap with which child? ::: The larger child. Can two array heaps merge in ? ::: No — placement/build-heap costs .


Connections