Proofs: Randomized quicksort
These are the human proofs of Randomized quicksort, at full length.
Randomized quicksort sorts the array on each run full
This proof shows: correctness.
Fix any sequence of values returned by the random choices of line L2, each with in its call. We prove that the run with these values sorts the array. Then the algorithm is correct with probability 1.
We write for the multiset of the items of at the start of a call.
Lemma (PARTITION). Assume . Then PARTITION returns an index with . After it, holds the same items, where is the old , each item of is at most , and each item of is larger than . Items outside the range do not change.
Proof. This is the Lomuto partition. Its loop keeps the invariant: , each item of is at most , each item of is larger than , and . It holds at the start with . A step with grows the second part. A step with swaps with the first item of the second part, or with itself if that part is empty, and then grows the first part. The loop ends with , and the last swap puts at index and a larger item, if there is one, at index . All moves are swaps inside the range.
Theorem. For each choice of the random values, after RANDOMIZED-QUICKSORT the range is sorted and holds , and no item outside the range changes.
Proof. By strong induction on .
Base. If , line L1 returns, and a range of at most one item is sorted.
Step. Let and assume the claim for all shorter ranges. Line L2 gives with , so the swap of line L3 is inside the range and keeps . By the lemma, line L4 gives with , the items at most in , and the items larger than in . The ranges of lines L5 and L6 have lengths and , both at most . By the hypothesis, line L5 sorts and changes nothing else; it permutes that part, so its items are still at most . Line L6 does the same for , whose items stay larger than . So the range is a sorted part with items at most , then , then a sorted part with items larger than . It is sorted, and since all moves were swaps inside the range, it holds .
Termination. Each call on items makes two calls on at most items each, for each choice of the random values. So each run stops after at most calls.