Quicksort Two Classic Sorting Algorithms Critical Components in the World’S Computational Infrastructure
Total Page:16
File Type:pdf, Size:1020Kb
2.3 Quicksort Two classic sorting algorithms Critical components in the world’s computational infrastructure. • Full scientific understanding of their properties has enabled us to develop them into practical system sorts. • Quicksort honored as one of top 10 algorithms of 20th century in science and engineering. ‣ quicksort Mergesort. last lecture ‣ selection • Java sort for objects. ‣ duplicate keys • Perl, Python stable sort. ‣ system sorts Quicksort. this lecture • Java sort for primitive types. • C qsort, Unix, g++, Visual C++, Python. th Algorithms in Java, 4 Edition · Robert Sedgewick and Kevin Wayne · Copyright © 2009 · January 22, 2010 4:05:04 PM 2 Quicksort Basic plan. • Shuffle the array. • Partition so that, for some j - element a[j] is in place - no larger element to the left of j no smaller element to the right of j - Sir Charles Antony Richard Hoare • Sort each piece recursively. 1980 Turing Award ‣ quicksort ‣ selection input Q U I C K S O R T E X A M P L E ‣ duplicate keys shu!e K R A T E L E P U I M Q C X O S partitioning element ‣ system sorts partition E C A I E K L P U T M Q R X O S not greater not less sort left A C E E I K L P U T M Q R X O S sort right A C E E I K L M O P Q R S T U X result A C E E I K L M O P Q R S T U X Quicksort overview 3 4 Quicksort partitioning Quicksort: Java code for partitioning Basic plan. private static int partition(Comparable[] a, int lo, int hi) • Scan i from left for an item that belongs on the right. { int i = lo, j = hi+1; • Scan j from right for item item that belongs on the left. while (true) Exchange a[i] and a[j]. { • while (less(a[++i], a[lo])) find item on left to swap • Continue until pointers cross. if (i == hi) break; v a[i] while (less(a[lo], a[--j])) find item on right to swap i j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if (j == lo) break; initial values -1 15 K R A T E L E P U I M Q C X O S if (i >= j) break; check if pointers cross scan left, scan right 1 12 K R A T E L E P U I M Q C X O S exch(a, i, j); swap exchange 1 12 K C A T E L E P U I M Q R X O S } scan left, scan right 3 9 K C A T E L E P U I M Q R X O S exch(a, lo, j); swap with partitioning item exchange 3 9 K C A I E L E P U T M Q R X O S return j; return index of item now known tobefore be in vplace scan left, scan right 5 6 K C A I E L E P U T M Q R X O S } lo hi exchange 5 6 K C A I E E L P U T M Q R X O S before v during v Յ v Ն v scan left, scan right 6 5 K C A I E E L P U T M Q R X O S lo hi i j !nal exchange 0 5 E C A I E K L P U T M Q R X O S after before v during v Յ v Ն v Յ v v Ն v result E C A I E K L P U T M Q R X O S lo hi i j lo j hi Partitioning trace (array contents before and after each exchange) during v Յ v Ն v after Յ v v Ն v Quicksort partitioning overview 5 6 i j lo j hi after Յ v v Ն v Quicksort partitioning overview lo j hi Quicksort partitioning overview Quicksort: Java implementation Quicksort trace public class Quick lo j hi 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { initial values Q U I C K S O R T E X A M P L E private static int partition(Comparable[] a, int lo, int hi) random shu!e K R A T E L E P U I M Q C X O S { /* see previous slide */ } 0 5 15 E C A I E K L P U T M Q R X O S 0 3 4 E C A E I K L P U T M Q R X O S public static void sort(Comparable[] a) 0 2 2 A C E E I K L P U T M Q R X O S { 0 0 1 A C E E I K L P U T M Q R X O S StdRandom.shuffle(a); 1 1 A C E E I K L P U T M Q R X O S shuffle needed for sort(a, 0, a.length - 1); 4 4 A C E E I K L P U T M Q R X O S performance guarantee 6 6 15 A C E E I K L P U T M Q R X O S } no partition 7 9 15 A C E E I K L M O P T Q R X U S for subarrays 7 7 8 A C E E I K L M O P T Q R X U S private static void sort(Comparable[] a, int lo, int hi) of size 1 8 8 A C E E I K L M O P T Q R X U S { 10 13 15 A C E E I K L M O P S Q R T U X if (hi <= lo) return; 10 12 12 A C E E I K L M O P R Q S T U X int j = partition(a, lo, hi); 10 11 11 A C E E I K L M O P Q R S T U X sort(a, lo, j-1); 10 10 A C E E I K L M O P Q R S T U X sort(a, j+1, hi); 14 14 15 A C E E I K L M O P Q R S T U X } 15 15 A C E E I K L M O P Q R S T U X } result A C E E I K L M O P Q R S T U X Quicksort trace (array contents after each partition) 7 8 Quicksort animation Quicksort: implementation details 50 random elements Partitioning in-place. Using a spare array makes partitioning easier (and stable), but is not worth the cost. Terminating the loop. Testing whether the pointers cross is a bit trickier than it might seem. Staying in bounds. The (j == lo) test is redundant (why?), but the (i == hi) test is not. Preserving randomness. Shuffling is needed for performance guarantee. Equal keys. When duplicates are present, it is (counter-intuitively) best algorithm position to stop on elements equal to the partitioning element. in order current subarray not in order http://www.sorting-algorithms.com/quick-sort 9 10 Quicksort: empirical analysis Quicksort: best case analysis Running time estimates: Best case. Number of compares is ~ N lg N. • Home pc executes 108 compares/second. • Supercomputer executes 1012 compares/second. insertion sort (N2) mergesort (N log N) quicksort (N log N) computer thousand million billion thousand million billion thousand million billion home instant 2.8 hours 317 years instant 1 second 18 min instant 0.3 sec 6 min super instant 1 second 1 week instant instant instant instant instant instant Lesson 1. Good algorithms are better than supercomputers. Lesson 2. Great algorithms are better than good ones. 11 12 Quicksort: worst case analysis Quicksort: average-case analysis 2 Worst case. Number of compares is ~ N / 2. Proposition I. The average number of compares CN to quicksort an array of N elements is ~ 2N ln N (and the number of exchanges is ~ ⅓ N ln N). Pf. CN satisfies the recurrence C0 = C1 = 0 and for N ! 2: C0 + C1 + ... + CN 1 CN 1 + CN 2 + ... + C0 C =(N + 1) + − + − − N N N partitioning left right partitioning probability • Multiply both sides by N and collect terms: NCN = N(N + 1) + 2(C0 + C1 + ... + CN 1) − • Subtract this from the same equation for N-1: NCN (N 1)CN 1 =2N +2CN 1 − − − − • Rearrange terms and divide by N(N+1): CN CN 1 2 = − + N +1 N N +1 13 14 Quicksort: average-case analysis Quicksort: summary of performance characteristics • Repeatedly apply above equation: Worst case. Number of compares is quadratic. N + (N-1) + (N-2) + … + 1 ~ N2 / 2. CN CN 1 2 • = − + N +1 N N +1 • More likely that your computer is struck by lightning. CN 2 2 2 = − + + previous equation N 1 N N +1 − Average case. Number of compares is ~ 1.39 N lg N. CN 3 2 2 2 = − + + + N 2 N 1 N N +1 • 39% more compares than mergesort. 2 − 2 2 − 2 = + + + ... + • But faster than mergesort in practice because of less data movement. 1 2 3 N +1 • Approximate sum by an integral: Random shuffle.