Exercises — Module 15 (External Sorting)
Self-contained problems on this module's material — replacement selection and the law, the tree of losers, and the polyphase merge with its Fibonacci distributions. You can work every one without the books: each states the problem in full, gives a hint to peek at when stuck, and a worked answer sketch to check against. Computational answers here are reproduced by the code you write in the lab (or a few lines at a REPL).
Ratings follow Knuth's scale (00–50; M = needs mathematics, ▶ =
especially instructive). Numbers like "cf. 5.4.1–1" point at the matching
exercise of Vol. 3 §5.4 for readers who own it.
Tracking
| # | Topic | Rating | Status |
|---|---|---|---|
| 1 | Replacement selection by hand, , sixteen keys | 10 | ⬜ |
| 2 | Reverse input runs of exactly | 15 | ⬜ |
| 3 | ▶ Loser-tree replay ; winner tree pays double | M22 | ⬜ |
| 4 | ▶ The 13-run/3-tape table; redo with 21 runs | 15 | ⬜ |
| 5 | Perfect distributions for ; the totals recurrence | M20 | ⬜ |
| 6 | ▶ Optimal dummy placement vs. append-at-back | M28 | ⬜ |
| 7 | First run has expected length | M30 | ⬜ |
Problems
1. Replacement selection by hand, , sixteen keys (rating 10 · cf. 5.4.1–1)
Problem. Run replacement selection (Algorithm R, §2) by hand with memory on Knuth's sixteen keys
Give the runs it produces and their lengths, and compare with the result from §2 (three runs of lengths ). What is special about the answer?
Hint. Keep the four in-memory records tagged by (run number, key); output the smallest, refill from the input, and freeze an arrival whose key is less than the last key output (tag it with the next run number). A run ends when every in-memory record is frozen.
Answer sketch. With the algorithm produces two runs, each of length exactly :
So records become runs of length — a clean illustration of Moore's law (§2): raising memory from to dropped the run count from to and pushed the average run length from to . (The first run being a full here, rather than the shorter of Problem 7, is luck of this particular short input; the law is a steady-state average.) Cross-check: a direct simulation of Algorithm R reproduces both runs and the lengths of the case.
2. Reverse input runs of exactly (rating 15 · cf. 5.4.1–3)
Problem. Prove that if the input is in strictly decreasing order, then replacement selection with memory produces runs of length exactly (until the tail). This is the worst case the §2 lesson names; stage 1 tests it, and here you write the argument.
Hint. After R1 fills memory with the first records, watch step R5. When the input is decreasing, how does each new arrival compare with the key just output?
Answer sketch. After R1, memory holds the first records, all tagged with the current run number . The algorithm outputs them in increasing key order. Consider any arrival read in R4 during run : it is later in the (decreasing) input than every record already read, so is smaller than every key seen so far, in particular smaller than LASTKEY (the key just output). By R5, , so is frozen with tag . Thus every arrival during run is frozen: run consists of exactly the records present in memory when it began, and no more. When those are output, all remaining in-memory records carry tag , so R2 closes run and the same argument repeats for run with the next records. Hence each run has length exactly — the worst case, since replacement selection can do no worse than sort-a-chunk. (Contrast §2's other extreme: already-sorted input never freezes anything and yields a single run.)
3. ▶ Loser-tree replay ; where a winner tree pays double (rating M22 · cf. 5.4.1–10)
Problem. In the tree of losers (§3) merging runs, show that after the champion is output and its run advances, restoring the tournament costs exactly key comparisons when is a power of two (and never more after padding up to the next power of two). Then explain where a winner tree — one storing the winner of each subtree at each node — pays up to two comparisons per level instead of one.
Hint. Only the matches on the path from the changed leaf to the root can change outcome. At each such node, who is the new entrant's opponent, and is it already sitting there? For the winner tree, ask what a node stores versus what the replay needs to compare against.
Answer sketch. Pad to so every leaf has depth exactly ; padding leaves are and matches against them are flag checks, not key comparisons. When the champion's leaf gets a new front record, the only matches whose outcome can change are those on that leaf-to-root path — everything else involves the same two subtrees as before. There are nodes on that path (one per level). At each, the climbing record meets the record already stored there, and — this is the whole point of a loser tree — that stored record is precisely the loser of the match previously played at that node, i.e. the best player from the other side of the match, the exact opponent the replay needs. So each level costs one comparison and touches one node: comparisons total (e.g. ; ).
A winner tree stores at each node the winner of the subtree below it. On
replay, the climber's true opponent is the best player of the sibling
subtree — but that is not what the node holds; the node holds the winner of the
climber's own subtree. To find the sibling's champion the replay must read
the sibling node and compare, then compare again to record the new subtree
winner — up to two node reads and two comparisons per level, roughly
. The loser tree keeps the right opponent in the exact place
the replay visits; that is why §3 (and stage 2's comparison-bound test,
) prefers it over both a winner tree and a
BinaryHeap (pop-then-push also costs up to two comparisons per level).
4. ▶ The 13-run/3-tape table; redo with 21 runs (rating 15 · cf. 5.4.2–1)
Problem. Reproduce §4's polyphase table for unit runs on tapes — perfect distribution , five phases — and verify the total merge I/O is records ( passes). Then redo the whole trace for runs on tapes: give the distribution, the per-phase records moved, the number of phases, and the total.
Hint. Perfect 3-tape totals are the Fibonacci numbers ; is itself perfect, so no dummies are needed. Each phase merges onto the currently empty tape until one input tape empties, and every other tape keeps its unread runs where they are.
Answer sketch. For : distribution ; phases move records, total , i.e. passes — beating balanced 2-way's full passes (), and on one fewer drive.
For : distribution is the next perfect level, , giving phases:
| phase | merge | onto | records moved |
|---|---|---|---|
| 1 | 8 groups | tape 3 | 16 |
| 2 | 5 groups | tape 2 | 15 |
| 3 | 3 groups | tape 1 | 15 |
| 4 | 2 groups | tape 3 | 16 |
| 5 | 1 group | tape 2 | 13 |
| 6 | 1 group | tape 1 | 21 |
Total records, i.e. passes. (Both traces reproduced by a direct polyphase simulation with unit runs.) The pattern to savor is §4's phase 2 analogue: the tape not chosen as output keeps its partially consumed reel exactly in place, which is why a phase moves only part of the file.
5. Perfect distributions for ; the totals recurrence (rating M20 · cf. 5.4.2–3)
Problem. Using the level recurrence of §4 for tapes,
compute the perfect distributions for from level up to a total of , and verify that the totals obey (the "tribonacci" law).
Hint. Apply the three update rules to each level (sorting the result non-increasing), and add the components to get each total. The totals should be .
Answer sketch. The levels and totals:
| level | distribution | total |
|---|---|---|
| 0 | 1 | |
| 1 | 3 | |
| 2 | 5 | |
| 3 | 9 | |
| 4 | 17 | |
| 5 | 31 | |
| 6 | 57 |
The totals satisfy : , , , . This is §4's generalized Fibonacci law at (three predecessors). The recurrence follows because reversing one perfect phase restores, to each surviving tape, the runs the exhausted tape consumed alongside it — exactly the level formula — and summing telescopes into the tribonacci sum. (All levels and the recurrence confirmed by direct computation.)
6. ▶ Optimal dummy placement vs. append-at-back (rating M28 · cf. 5.4.2–13)
Problem. Real files rarely have a perfect number of runs, so §4 pads with dummy runs — imaginary runs of length zero that merge for free. The lab uses the simplest convention: append the dummies at the back of each tape's quota. Knuth instead places dummies where they are merged fewest times. Show that placement matters, and quantify the saving in total record I/O for real runs on tapes.
Hint. The smallest perfect 3-tape total is (distribution ), so you deal real runs and dummies. A dummy has length , so it never moves a record itself — but where it sits changes how many phases each real run survives, hence how many times each real record is copied. Simulate the polyphase merge for different dummy positions and total the records moved.
Answer sketch. With , : perfect total , distribution , dummies. Simulating the merge with unit-length real runs and length- dummies, the total record I/O ranges over placements from (best) to (worst). The lab's append-at-back convention (tape 1 real; tape 2 real then dummies at the back) costs . The optimal placement puts each dummy at the front of an input tape, so it is consumed in phase 1 — merged exactly once, the fewest possible — costing . The saving is records (about of the merge I/O at this tiny size). The mechanism, matching §4: a dummy merged early frees a slot so a real run enters fewer subsequent merges; a dummy that lingers (append-at-back) drags real records through extra phases. The saving grows with and , which is why Knuth's Algorithm 5.4.2D tracks dummy positions ( counters) rather than dumping them at the back. (Best/worst/ convention totals all reproduced by exhaustive simulation over the dummy placements.)
7. First run has expected length (rating M30 · cf. 5.4.1–21)
Problem. §2's snow-plow argument gives expected steady-state run length . But the first run is special: the lesson states its expected length is , shorter than . Explain why, in terms of the snow-plow picture, and confirm the constant.
Hint. The steady state assumes the track already carries its equilibrium units of snow spread uniformly. When the very first run begins, how much snow is on the ground? What does the plow eat on a lap over a track that starts bare and is only now accumulating?
Answer sketch. The law is a steady-state result: it assumes the "track" already holds its equilibrium load of frozen records spread uniformly, so a lap sweeps depth everywhere and the run length is (§2). The first run starts from a bare track — memory was just filled in R1 with records but nothing has been frozen yet, so there is no pre-accumulated snow ahead of the plow. The plow eats only the snow that falls during its first lap over ground that is still filling up, so the first run is shorter. Carrying out the same conservation calculation with the bare-track initial condition (the accumulation integral now runs over a track building up from empty rather than a full uniform load) yields expected first-run length . Numerically , so the first run averages about against the steady-state — which is exactly the caveat §2 attaches to its stage-1 experiment (, : the overall average lands near because the short first run is diluted by the long steady-state tail). The constant is confirmed to the stated precision, and a simulation of first-run lengths over random inputs tracks .
Your solutions
Use this space to log your own work — a restated problem, your approach, and how it compared with the sketch above.
Exercise N (rating RR)
Approach. Answer / proof. Compared with the sketch: what you did differently, what you missed.