Proofs: Dijkstra's three-way partition
These are the human proofs of Dijkstra's three-way partition, at full length.
Dijkstra's three-way partition is correct and inspects each item exactly once full
This proof shows: correctness, termination.
We use the pseudocode of the page. Let be the input array, of length , and the pivot value. Write for "every item of the range is less than ", and the same for and ; an empty range satisfies each of these.
Claim. THREE-WAY-PARTITION runs the loop of line L2 exactly times. On return, is a permutation of , and the returned pair satisfies , and .
Proof. We show that this invariant holds at each test of line L2:
(F) ; is a permutation of ; ; ; .
Initialization. Line L1 sets and . Then , , and the three ranges , and are empty.
Maintenance. Assume (F) and , so and exists. Let . Write primes for the values after the iteration.
- Case (line L4). If , then is in the range , so by (F). After the swap, and . If , the swap changes nothing and . In both cases the other cells do not change. Now and . The range minus its last cell is , and its last cell , so . The range is the range , which is , plus the cell , which is when ; when the range is empty. The last region does not change. The bounds hold since .
- Case (line L6). After the swap, , and . So is the cell followed by . The cells do not change, because and the swap touches only and . The bounds hold: .
- Case (line L7). , and . Nothing else changes, and .
Each case only swaps two cells, so is still a permutation of . So (F) holds again.
Termination and count. Let . By (F), , and the loop runs while . Line L4 adds 1 to , line L6 subtracts 1 from and line L7 adds 1 to ; in each case decreases by exactly 1. It starts at , so the loop runs exactly times and stops with .
Result. When the loop stops, . Line L8 returns and . By (F), , , and , and is a permutation of .
Each item is inspected once. The value is compared with once in each iteration. Call the cells the unknown region. An item is compared only when it is at , inside the unknown region, and after the comparison it leaves this region in each case: by in lines L4 and L7, and by the swap to position and in line L6. Items enter the unknown region never; the item that line L6 moves to position was already in it. So each of the items is compared in exactly one iteration, which matches the count .
Swap count. Line L4 runs once for each item less than and line L6 once for each item greater than , since each iteration handles the item it inspects. So the number of swaps is the number of items different from .