Download presentation
Presentation is loading. Please wait.
Published byMitchell Fields Modified over 9 years ago
1
Recursive Quicksort Data Structures in Java with JUnit ©Rick Mercer
2
Quicksort: O(n log n) Sorting Quicksort was discovered by Tony Hoare 1962 Here is an outline of his famous algorithm: Pick one item from the array--call it the pivot Partition the items in the array around the pivot so all elements to the left are to the pivot and all elements to the right are greater than the pivot Use recursion to sort the two partitions a snapshot pivot partition: items > pivot partition 1: items pivot
3
Before and After Let's sort integers Pick the leftmost one (27) as the pivot value The array before call to partition(a, 0, n-1) Array looks like this after first partition is done 27 14 9 22 8 41 56 31 14 53 99 11 2 24 24 14 9 22 8 14 11 2 27 53 99 56 31 41 pivotitems < pivotitems > pivot
4
The partition method p artition divvies up a around the split and returns the position of the split, an integer in the range of 0..n-1 The postcondition of partition: a[first]..a[split-1] <= a[split] && a[split+1]..a[last] > a[split] Notes: May be more than 1 element equal to the pivot Put them in left partition could have been the right
5
Recursive call to sort smaller part of the array quickSort(a, split+1, last); // sort right QuickSort the right. At some point Pivot will be 53 Assume left portion is already sorted 24 14 9 22 8 14 11 2 27 53 99 56 31 41 2 8 9 11 14 14 22 24 27 31 41 53 99 56 pivot items < pivotitems > pivot left is already sorted, begin to sort part to the right of split
6
Complete the sort // sort left and right around new split // sort left and right around new split quickSort(a, first, split-1); quickSort(a, first, split-1); // sort right // sort right quickSort(a, split+1, last); quickSort(a, split+1, last); 2 8 9 11 14 14 22 24 27 31 41 53 99 56 2 8 9 11 14 14 22 24 27 31 41 53 56 99 Entire array is now sorted
7
Start Over (i ==1) Start Over (i ==1) Now let's back up and start with empty partitions int partition(int a[], int first, int last) { int lastSmall = first; int lastSmall = first; int i = (first + 1); // Beginning of unknowns int i = (first + 1); // Beginning of unknowns Compare all items from a[i]..a[last] if a[i] > a[first] (the pivot), do nothing if a[i] <= a[first], swap a[lastSmall+1] with a[i] 27 41 14 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items (all are unknown--except first)
8
Result of the 1st loop iteration(i==2) 27 41 14 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot The following array shows no changes were made in the array since a[i] <= a[first] was false So simply add 1 to i (i++)--create 2 partitions Now partition 1 has one element (the pivot 27) and partition 2 has 1 element (41)
9
Result of the 2nd loop iteration(i==3) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot The following array shows a swap was made in the array since a[i] <= a[first] was true (14 < 27) a[i] (14) is swapped with a[lastSmall+1] (41) lastSmall gets incremented to point to the last element in partition 1 i gets incremented to reference 56
10
Result of the 3rd loop iteration(i==4) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot The following array shows no swap was made in the array since a[i] <= a[first] was false lastSmall does NOT get incremented i gets incremented to reference 31
11
Result of the 4th loop iteration(i==5) 27 14 41 56 31 9 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot The following array shows no swap was made in the array since a[i] <= a[first] was false lastSmall does NOT get incremented i gets incremented to reference 9
12
Result of the 5th loop iteration(i==6) 27 14 9 56 31 41 22 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot The following array shows a swap was made in the array since a[i] <= a[first] was true (9 < 27) a[i] (9) is swapped with a[lastSmall+1] (41) lastSmall gets incremented to point to the last element in partition 1 i++ points to the first unknown (22)
13
27 14 9 22 56 31 41 8 14 53 99 11 2 24 first lastSmall i unknown items partition 1: all items pivot i == 7
14
27 14 9 22 8 56 31 41 14 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 8
15
27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 9
16
27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 10
17
27 14 9 22 8 14 56 31 41 53 99 11 2 24 first lastSmall i unknown partition 1: all items pivot i == 11
18
27 14 9 22 8 14 11 56 31 41 53 99 2 24 first lastSmall i unknown partition 1: all items pivot i == 12
19
27 14 9 22 8 14 11 2 56 31 41 53 99 24 first lastSmall i unknown partition 1: all items pivot i == 13
20
Result of the 14th loop iteration(i==14) 27 14 9 22 8 14 11 2 24 53 99 56 31 41 first lastSmall i partition 1: all items pivot The following array shows what happens after traversing the entire array with this loop (i>last): for (i = first + 1; i <= last; i++) { if(a[i] <= a[first] ) { if(a[i] <= a[first] ) { lastSmall++; lastSmall++; swapElements(a, lastSmall, i); swapElements(a, lastSmall, i); } }
21
Post Loop Detail Now place the pivot into where we expect the pivot to be: in-between the two partitions swapElements( a, first, lastSmall ); swapElements( a, first, lastSmall ); Then we can return lastSmall for the next call return lastSmall; return lastSmall; 24 14 9 22 8 14 11 2 27 53 99 56 31 41 first lastSmall (pivot position) partition 1: all items pivot
22
quickSort is called like this: quickSort(a, 0, n-1) void quickSort(int a[], int first, int last) { void quickSort(int a[], int first, int last) { // precondition: a is an array to be sorted from // precondition: a is an array to be sorted from // a[first]..a[last] // a[first]..a[last] if(first >= last) if(first >= last) return; // Done: we have an empty array return; // Done: we have an empty array // The difficult algorithm is in partition // The difficult algorithm is in partition int split = partition ( a, first, last ); int split = partition ( a, first, last ); // Recursively Quicksort left, then right // Recursively Quicksort left, then right quickSort(a, first, split-1); // sort left quickSort(a, first, split-1); // sort left quickSort(a, split+1, last); // sort right quickSort(a, split+1, last); // sort right // post: the array a is sorted // post: the array a is sorted }
23
Analyzing Quicksort The critical statement happens in the comparison of the for loop of the partition function if(a[i] <= a[first]) if(a[i] <= a[first]) So how many times is partition called? And what are the values for first and last (# comparisons)? If the pivot element is near the mode, we don't have many calls to QuickSort, it is O(log n)
24
The best of Quicksort, the worst of Quicksort In the best case (1st element is always middle value) with 7 elements, call partition 3 times first == 0, last == 6 // 6 comparisons first == 0, last == 6 // 6 comparisons first == 0, last == 2 // 2 comparisons first == 0, last == 2 // 2 comparisons first == 4, last == 6 // 2 comparisons first == 4, last == 6 // 2 comparisons In the worst case, (sorted array), with 7 elements, partition is called first == 0, last == 6 // 6 comparisons first == 0, last == 6 // 6 comparisons first == 1, last == 6 // 5 comparisons first == 1, last == 6 // 5 comparisons first == 2, last == 6 // 4 comparisons first == 2, last == 6 // 4 comparisons first == 3, last == 6 // 3 comparisons first == 3, last == 6 // 3 comparisons first == 4, last == 6 // 2 comparisons first == 4, last == 6 // 2 comparisons first == 5, last == 6 // 1 comparison first == 5, last == 6 // 1 comparison
25
Best Case: [ 4, 1, 3, 2, 6, 5, 7 ] [ 4, 1, 3, 2, 6, 5, 7 ] [ 2, 1, 3, 4, 6, 5, 7 ] [ 2, 1, 3, 4, 6, 5, 7 ] [ 2, 1, 3] [ 6, 5, 7 ] [ 2, 1, 3] [ 6, 5, 7 ] [ 1, 2, 3] [ 5, 6, 7 ] [ 1, 2, 3] [ 5, 6, 7 ] [1] [3] [5] [7] [1] [3] [5] [7]
26
Worst Case [ 1, 2, 3, 4, 5, 6, 7] [] [2, 3, 4, 5, 6, 7] [] [2, 3, 4, 5, 6, 7] [] [3, 4, 5, 6, 7] [] [3, 4, 5, 6, 7] [] [4, 5, 6, 7] [] [4, 5, 6, 7] [] [5, 6, 7] [] [5, 6, 7] [] [6, 7] [] [6, 7] [] [7] [] [7] [] [] [] []
27
The Best and Worst continued So in the worst case, partition is called n-1 times: (n-1)+(n-2)+... + 1 comparisons = O(n 2 ) The worst case of Quicksort may be the same as Selection Sort, which is O(n 2 ) Quicksort is used because of its best and average cases
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.