Quick Sort Data Structures in Java with JUnit

  • Slides: 27
Download presentation
Quick. Sort Data Structures in Java with JUnit ©Rick Mercer

Quick. Sort Data Structures in Java with JUnit ©Rick Mercer

Quicksort: O(n log n) Sorting w Quicksort was discovered by Tony Hoare 1962 w

Quicksort: O(n log n) Sorting w Quicksort was discovered by Tony Hoare 1962 w 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 partition 1: items pivot partition: items > pivot

Before and After w Let's sort integers ¾ ¾ Pick the leftmost one (27)

Before and After w Let's sort integers ¾ ¾ Pick the leftmost one (27) as the pivot value The array before call to partition(a, 0, n-1) 27 14 9 22 8 41 56 31 14 53 99 11 2 24 ¾ Array looks like this after first partition is done 24 14 9 22 8 14 11 items < pivot 2 27 53 99 56 31 41 pivot items > pivot

The partition method w partition divvies up a around the split and returns the

The partition method w partition 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] w Notes: May be more than 1 element equal to the pivot ¾ Put them in left partition could have been the right ¾

Recursive call to sort smaller part of the array quick. Sort(a, split+1, last); //

Recursive call to sort smaller part of the array quick. Sort(a, split+1, last); // sort right w. Quick. Sort the right. At some point Pivot will be 53 ¾ And the left portion will be sorted ¾ 24 14 9 22 8 14 11 2 27 53 99 56 31 41 left is already sorted, begin to sort part to the right of split 2 8 9 11 14 14 22 24 27 31 41 53 99 56 pivot items < pivot items > pivot

Complete the sort // sort left and right around new split quick. Sort(a, first,

Complete the sort // sort left and right around new split quick. Sort(a, first, split-1); 2 8 9 11 14 14 22 24 27 31 41 53 99 56 // sort right quick. Sort(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

Start Over (i ==1) w Now let's back up and start with empty partitions

Start Over (i ==1) w Now let's back up and start with empty partitions int partition(int a[], int first, int last) { int last. Small = first; int i = (first + 1); // Beginning of unknowns first last. Small i 27 unknown items (all are unknown--except first) 41 14 56 31 9 22 8 14 53 99 11 2 24 w Compare all items from a[i]. . a[last] ¾ ¾ if a[i] > a[first] (the pivot), do nothing if a[i] <= a[first], swap a[last. Small+1] with a[i]

Result of the 1 st loop iteration(i==2) The following array shows no changes were

Result of the 1 st loop iteration(i==2) 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) ¨ first last. Small i 27 unknown items 41 14 56 31 9 22 8 14 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

Result of the 2 nd loop iteration(i==3) The following array shows a swap was

Result of the 2 nd loop iteration(i==3) 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[last. Small+1] (41) ¨ last. Small gets incremented to point to the last element in partition 1 ¨ i gets incremented to reference 56 ¨ first last. Small i 27 unknown items 14 41 56 31 9 22 8 14 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

Result of the 3 rd loop iteration(i==4) The following array shows no swap was

Result of the 3 rd loop iteration(i==4) The following array shows no swap was made in the array since a[i] <= a[first] was false ¨ last. Small does NOT get incremented ¨ i gets incremented to reference 31 ¨ first last. Small i 27 unknown items 14 41 56 31 9 22 8 14 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

Result of the 4 th loop iteration(i==5) The following array shows no swap was

Result of the 4 th loop iteration(i==5) The following array shows no swap was made in the array since a[i] <= a[first] was false ¨ last. Small does NOT get incremented ¨ i gets incremented to reference 9 ¨ first last. Small 27 14 41 56 31 i unknown items 9 22 8 14 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

Result of the 5 th loop iteration(i==6) w The following array shows a swap

Result of the 5 th loop iteration(i==6) w The following array shows a swap was made in the array since a[i] <= a[first] was true (9 < 27) w a[i] (9) is swapped with a[last. Small+1] (41) w last. Small gets incremented to point to the last element in partition 1 w i++ points to the first unknown (22) first last. Small 27 14 i unknown items 9 56 31 41 22 8 14 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

i == 7 first last. Small 27 14 i 9 22 31 41 56

i == 7 first last. Small 27 14 i 9 22 31 41 56 partition 1: all items <= pivot unknown items 8 14 53 99 11 2 24 partition 2: all items > pivot

i == 8 first last. Small 27 14 9 22 8 i 41 56

i == 8 first last. Small 27 14 9 22 8 i 41 56 31 partition 1: all items <= pivot unknown 14 53 99 11 2 24 partition 2: all items > pivot

i == 9 first last. Small 27 14 i unknown 9 22 8 14

i == 9 first last. Small 27 14 i unknown 9 22 8 14 56 31 41 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

i == 10 first last. Small 27 14 i unknown 9 22 8 14

i == 10 first last. Small 27 14 i unknown 9 22 8 14 56 31 41 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

i == 11 first last. Small 27 14 i unknown 9 22 8 14

i == 11 first last. Small 27 14 i unknown 9 22 8 14 56 31 41 53 99 11 2 24 partition 1: all items <= pivot partition 2: all items > pivot

i == 12 first last. Small 27 14 i unknown 9 22 8 14

i == 12 first last. Small 27 14 i unknown 9 22 8 14 11 31 41 53 99 56 2 24 partition 1: all items <= pivot partition 2: all items > pivot

i == 13 first last. Small 27 14 i unknown 9 22 8 14

i == 13 first last. Small 27 14 i unknown 9 22 8 14 11 2 41 53 99 56 31 24 partition 1: all items <= pivot partition 2: all items > pivot

Result of the 14 th loop iteration(i==14) ¨ The following array shows what happens

Result of the 14 th loop iteration(i==14) ¨ 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] ) { last. Small++; swap. Elements(a, last. Small, i); } } first 27 last. Small 14 9 22 8 14 11 partition 1: all items <= pivot 2 24 i 53 99 56 31 41 partition 2: all items > pivot

Post Loop Detail w Now place the pivot into where we expect the pivot

Post Loop Detail w Now place the pivot into where we expect the pivot to be: in-between the two partitions swap. Elements( a, first, last. Small ); w Then we can return last. Small for the next call return last. Small; first 24 last. Small (pivot position) 14 9 22 8 14 11 partition 1: all items <= pivot 2 27 53 99 56 31 41 partition 2: all items > pivot

quick. Sort is called like this: quick. Sort(a, 0, n-1) void quick. Sort(int a[],

quick. Sort is called like this: quick. Sort(a, 0, n-1) void quick. Sort(int a[], int first, int last) { // precondition: a is an array to be sorted from // a[first]. . a[last] if(first >= last) return; // Done: we have an empty array // The difficult algorithm is in partition int split = partition ( a, first, last ); // Recursively Quicksort left, quick. Sort(a, first, split-1); quick. Sort(a, split+1, last); } // post: the array a is sorted then right // sort left // sort right

Analyzing Quicksort w The critical statement happens in the comparison of the for loop

Analyzing Quicksort w The critical statement happens in the comparison of the for loop of the partition function if(a[i] <= a[first]) ¾ ¾ So how many times is partition called? And what are the values for first and last (# comparisons)? w If the pivot element is near the mode, we don't have many calls to Quick. Sort, it is O(log n)

The best of Quicksort, the worst of Quicksort w In the best case (1

The best of Quicksort, the worst of Quicksort w In the best case (1 st element is always middle value) with 7 elements, call partition 3 times first == == == 0, 0, 4, last == == == 6 2 6 // // // 6 2 2 comparisons w In the worst case, (sorted array), with 7 elements, partition is called first first == == == 0, 1, 2, 3, 4, 5, last last == == == 6 6 6 // // // 6 5 4 3 2 1 comparisons comparisons comparison

Best Case: [ 4, 1, 3, 2, 6, 5, 7 ] [ 2, 1,

Best Case: [ 4, 1, 3, 2, 6, 5, 7 ] [ 2, 1, 3, 4, 6, 5, 7 ] [ 2, 1, 3] [ 6, 5, 7 ] [ 1, 2, 3] [ 5, 6, 7 ] [1] [3] [5] [7]

Worst Case [ 1, 2, 3, 4, 5, 6, 7] [] [3, 4, 5,

Worst Case [ 1, 2, 3, 4, 5, 6, 7] [] [3, 4, 5, 6, 7] [] [5, 6, 7] [] [7] [] []

The Best and Worst continued w So in the worst case, partition is called

The Best and Worst continued w So in the worst case, partition is called n-1 times: (n-1)+(n-2)+. . . + 1 comparisons = O(n 2) w The worst case of Quicksort may be the same as Selection Sort, which is O(n 2) w Quicksort is used because the average case os O(n log n)