QuickSort Jeff Chastine Properties of QuickSort • Runs in (n2) worst case, but (n lg n) on average • Constants in the (n lg n) are small, so it’s often the best practical sorting algorithm • Sorts in place • Several variations: – randomized partitioning – random sampling Jeff Chastine Overview of QuickSort • Divide: The array [p..r] is partitioned into two non-empty subarrays A[p..q] and A[q+1 .. r] such that each element in the first array is less than or equal to each item in the second • Conquer: Sort recursively • Combine: Since they are already sorted Jeff Chastine QuickSort QUICKSORT (A, p, r) if p < r then q ← PARTITION (A, p, r) QUICKSORT (A, p, q) QUICKSORT (A, q+1, r) Note: obviously, PARTITION is the key here! Jeff Chastine Partitioning • PARTITION selects a pivot element for partitioning • We have a range p to r in A with two variables i and j, and a pivot point x, initialized to r. • At the beginning of each loop: – Everything between p and i is x – Everything between i and j is > x Jeff Chastine Jeff Chastine i p,j 2 r 8 7 1 3 5 6 4 Jeff Chastine p,i j 2 8 r 7 1 3 5 6 4 Jeff Chastine p,i 2 j 8 7 r 1 3 5 6 4 Jeff Chastine p,i 2 j 8 7 1 r 3 5 6 4 Jeff Chastine p i 2 1 j 7 8 3 r 5 6 4 Jeff Chastine p 2 i 1 3 j 8 7 5 r 6 4 Jeff Chastine p 2 i 1 3 8 7 5 j r 6 4 Jeff Chastine p 2 i 1 3 r 8 7 5 6 4 Jeff Chastine p 2 i 1 r 3 4 7 5 This is in the correct spot! 6 8 PARTITION PARTITION (A, p, r) 1 x ← A[r] 2 3 4 5 6 7 8 i← p-1 for j p to r – 1 do if A[j] x then i ← i + 1 exchange A[i] A[j] exchange A[i + 1] A[r] return i + 1 Jeff Chastine Performance • Depends heavily on whether the partitioning is balanced • Unbalanced can run as slow as insertion sort! • Worst-case: two subproblems with – n – 1 elements – 0 elements • T (n) = T (n – 1) + T (0) + (n) • Decomposes to (n2) Jeff Chastine What’s really going on... • Average time not close to that... • Suppose that we have a 9-to-1 split: T (n) = T (9n/10) + T (n/10) + cn • Then, a subproblem at depth i is 9in/10i – Solving for i yields a tree of depth log10/9 n • Thus, the height of the tree is still logarithmic! • Even a 99-to-1 split is logarithmic • Any split of constant proportionality yields a tree of depth (n) • Note: 80% of the time, PARTITION produces a split more balanced than 9-to-1 Jeff Chastine Randomized Quicksort • Uses random sampling • Use a randomly chosen element from the array • Swap A[r] with the chosen element RANDOMIZED-PARTITION (A, p, r) 1 i RANDOM (p, r) 2 exchange A[r] A[i] 3 return PARTITION (A, p, r) Jeff Chastine Summary • • • • • Runs in O(n log n) on average Runs in O(n2) in worst-case It uses partitioning to sort Randomized partitioning helps Quicksort is preferred, because of its low constant factors Jeff Chastine