Proofs: Quicksort
These are the human proofs of Quicksort, at full length.
Quicksort sorts the array and keeps its items full
This proof shows: correctness.
We write for the multiset of the items of at the start of a call. Each step of the algorithm changes the array only by a swap, so the multiset of the items of the full array never changes.
Lemma (PARTITION). Assume that . Then PARTITION returns an index with . After the call, holds , (the old ), each item of is at most , and each item of is larger than . No item outside changes.
Proof. Line L5 sets , and line L6 sets . We use this invariant for the loop of line L7, before the step for :
(P) . Each item of is at most . Each item of is larger than . .
Start. For , both parts are empty and . Nothing has moved, so .
Step. Assume (P) before the step for . If , the step changes nothing, and is a part of items larger than . So (P) holds for . If , line L9 swaps and . If , then was in the part of larger items, so after the swap and . If , the swap changes nothing. In both cases, after line L10, each item of is at most , and each item of is larger than . So (P) holds for . The swap uses indices , so does not change.
End. The loop runs once for each from to , so it stops after steps with . By (P), , and . Line L11 swaps and . If , the item at was larger than , and it goes to index , which is in the right part. If , the swap changes nothing. So with , the claim holds. All changes were swaps inside the range, so the range holds and nothing outside it changed.
Theorem. After QUICKSORT, the part is sorted and holds . No other item of changes.
Proof. By strong induction on .
Base. If , line L1 returns. A part with at most one item is sorted, and nothing changed.
Step. Let , and assume the claim for all ranges of length less than . By the lemma, line L2 gives with , a left part of items at most , and a right part of items larger than . The ranges of lines L3 and L4 have lengths and . Both are at most , because the index is in neither range. By the induction hypothesis, line L3 sorts the left part and changes nothing else, so it does not change or the right part. It permutes the left part, so all its items are still at most . In the same way, line L4 sorts the right part and keeps its items larger than .
Now is sorted with each item at most , , and is sorted with each item larger than . So is sorted. Each step was a swap inside the range, so it holds .
Termination. Each call on a range of length makes two calls on ranges of length at most . So the depth of the recursion is at most , and the algorithm stops.