chapter 11 sorting. selection sort 0 1 n-2 n-1index 2 4 1 3 第 0 回合 第 1 回合 2 4 13 2 4 31...
TRANSCRIPT
Chapter 11
Sorting
Selection Sort
0 1 n-2 n-1index
2413 第 0 回合
第 1 回合
2413
2431
3421 第 n-2 回合
4321
min
min
min
每回合處理 a[i … n-1] ,而 i 從 0 到 n-2Select min ,與 a[ i ] swap1. 令 a[ i ] 為 min2. If a[ j+1] < min ,then 令 a[ j+1] 為 min, 而 j 從 i
到 n-1
Select( int[n] a) { for( i = 0, i <= n-2, i++){ min = i ; for( j = i, j <= n-1, j++) if a[ j + 1] < a[min] min=j+1; swap( a[min], a[ i ]); }}
/** * @author 曾繼禾 * This class implement the selection sort. * Have these method : sort, swap, print. * Have parameter : array. *//*** Do the sorting job* @return The array have been sorted*/public int[] selectionSort(int[] array){
for(int i = 0; i < array.length; i++){
int min = i;for(int j = i; j < array.length; j++){
if(array[j] < array[min])min = j;
}array = swap(array, min, i);
}return array;
}
Selection.java
/** * Print the array of this object */public void print(){
for(int i = 0; i < array.length; i++)System.out.print(array[i] + " ");
System.out.println();}
/** * This methd is used to swap two position of value in one array * @param input Input array * @param a The first position to swap * @param b The second position to swap * @return Return the swaped array */public int[] swap(int[] input, int a, int b){
int temp = input[a];input[a] = input[b];input[b] = temp;return input;
}public int[] getArray() {
return array;}public void setArray(int[] array) {
this.array = array;}
}
Selection.java(continued)
Main.java/** * @author 曾繼禾 * * This is main class, using Selection object to do selection sort * * Have method : main */
/** * The main method, program start from here * @param args */public static void main(String[] args) {
int[] x = { 3, 1, 4, 2 };print(x);selectionSort(x);print(x);
}
Insertion Sort
3 1 4 2
0 1 n-2 n-1index
4 23 1 第一回合
第二回合
第 n-1 回合
1 3 24
1 3 4 2
1 2 3 4
每回合處理 a[i … n-1] ,而 i 從 1 到 n-1把 a[i] instert 到左邊排序位置(if a[j]<a[j-1] then swap else 不做 而 j 從 i 到 1)
InsertionSort(int[n] a){ for(i=1;i<=n-1;i++) for(j=I;j>=1;j--) if a[j]<a[j-1] swap(a[j],a[j-1]) else break; }void swap(int a,int b) { int temp; temp=a; a=b; b=temp; }
/** * @author 黃柏昇 * This class implement the Insertion sort. * Have these method : sort, swap, print. * Have parameter : array. *//** * Do the sorting job * @return The array have been sorted */public void insertionSort(int[] array){ for(int i = 1; i <= array.length-1; i++) {
for(int j = i; j >= 1; j--) { if(array[j] < array[j-1]) array = swap(array, array[j],array[j-1]); }
}return array;}
Insertion.java
/* Print the array of this object*/public void print(){for(int i = 0; i < array.length; i++)System.out.print(array[i] + " ");System.out.println();}
/** * This methd is used to swap two position of value in one array * @param input Input array * @param a The first position to swap * @param b The second position to swap * @return Return the swaped array */public int[] swap(int[] input, int a, int b){int temp = input[a];input[a] = input[b];input[b] = temp;return input;}public int[] getArray() {return array;}public void setArray(int[] array) {this.array = array;}
Insertion.java(continued)
/** * The main method, program start from here * @param args */public static void main(String[] args) {int[] x = { 3, 1, 4, 2 };
print(x);insertionSort(x);print(x);
}
Insertion.java(continued)
Bubble Sort
3
1
4
2
3
1
4
2
1
3
2
1
2
index
0
1
2
n-1
第 n-1 回合 第 n-2 回合 第 1 回合
44
3
4 3 2 1
每回合處理 a[0 … i] ,而 i 從 n-1 到 1(if a[j]<a[j+1] then swap 而 j 從 0 到 i-1)
BubbleSort(int[n] a){ for(i=n-1;i>=1;i--) for(j=0;j<=i-1;j++) if a[j]>a[j+1] swap(a[j],a[j+1]);}void swap(int a,int b) { int temp; temp=a; a=b; b=temp; }
/** * @author 黃柏昇 * This class implement the Bubble sort. * Have these method : sort, swap, print. * Have parameter : array. *//** * Do the sorting job * @return The array have been sorted */public void bubbleSort(int[] array){ for(int i = array.length-1; i >= 1; i--) {
for(int j = 0; j <= i-1; j++) {
if(array[j] > array[j+1]) array = swap(array, array[j],array[j+1]);
}
}return array;}
Bubble.java
/* Print the array of this object*/public void print(){for(int i = 0; i < array.length; i++)System.out.print(array[i] + " ");System.out.println();}
/** * This methd is used to swap two position of value in one array * @param input Input array * @param a The first position to swap * @param b The second position to swap * @return Return the swaped array */public int[] swap(int[] input, int a, int b){int temp = input[a];input[a] = input[b];input[b] = temp;return input;}public int[] getArray() {return array;}public void setArray(int[] array) {this.array = array;}
Bubble.java(continued)
/** * The main method, program start from here * @param args */public static void main(String[] args) {
int[] x = { 2, 4, 1, 3 };print(x);bubbleSort(x);print(x);
}
Bubble.java(continued)
Quick Sort
快速排序法 Quick Sort• Quicksort example
pivot i j
result
令 a[left] 為 pivot ( 即 3)
a
index 0 1 2 n-2 n-1left right
3 8 1 4 2令 i 為 left+1, j 為 right
1. while a[i] < pivot, i 向右移2. while a[j] >= pivot, j 向左移3. if (i<j), a[i] 和 a[j] 互換repeat until (i>j)
quickSort(a,left,j-1)
quickSort(a,j+1,right)
3 8 1 4 2
a[left] 和 a[j] 互換1 2 3 4 8
left rightright left
如果 a 為空或 left>=right 則結束
1 2 3 4 8
Quick Sort AlgorithmquickSort(int[] a, int left, int right){
int pivot = a[left]; int i = left+1, j = right; do{ while( a[i] < pivot ){ i++; }
while( a[j] >= pivot ){ j++; } if ( i < j ){ swap(a[i],a[j]) }
}while( i <= j)
swap(a[left], a[j]); quickSort(a, left, j-1); quickSort(a, j+1, right); }
Quick Sort/** * @author 胡升瑞 * This class implement the Quick Sort. * Have these method : QuickSort, swap, print. * Have parameter : array. */public void quickSort(int[] array, int low, int high) {
if (array == null || array.length == 0){return;}if (low >= high){return;}
//pick the pivotint pivot = array[low];//make left < pivot and right > pivotint i = low, j = high;while (i <= j) {
while (array[i] < pivot) {i++;}while (array[j] > pivot) {j--;}
if (i <= j) {swap(array,i,j); i++; j--;}}}//recursively sort two sub partsif (low < j){quickSort(array, low, j);}
if (high > i){quickSort(array, i, high);}}
Quick Sort(cont.)
/*Print the array of this object*/public void print(int[] x) {
for (int a : x)System.out.print(a + " ");System.out.println();
}/** * This methd is used to swap two position of value in one array * @param input Input array * @param a The first position to swap * @param b The second position to swap * @return Return the swaped array */public int[] swap(int[] input, int a, int b){
int temp = input[a];input[a] = input[b];input[b] = temp;return input;
}
Quick Sort(cont.)/** * The main method, program start from here * @param args */public static void main(String[] args) {
int[] x = { 3, 8, 1, 4, 2 };print(x);
int low = 0;int high = x.length - 1;
quickSort(x, low, high);print(x);
}
Assumptions:
Comparison-based sorts: Sorting is accomplished by comparing elements to each other.
We will sort sequences only:
Array ArrayList LinkedList
For now, assume we want to sort
x [0], x [1], …, x [n – 1], an array of n int values into increasing order.
Here is the method specification and a test method for Insertion Sort, one of the sorts in this chapter:
/** * Sorts a specified array of int values into ascending order. * The worstTime(n) is O(n * n). * * @param x - the array to be sorted. * * @throws NullPointerException - if x is null. * */ public static void insertionSort (int[ ] x) @Test public void testSample() { int [ ] expected ={12, 16, 17, 32, 33, 40, 43, 44, 46, 46, 50, 55, 59, 61, 75, 80, 80, 81, 87, 95}; int [ ] actual = {59, 46, 32, 80, 46, 55, 50, 43, 44, 81, 12, 95, 17, 80, 75, 33, 40, 61, 16, 87}; Sorts.insertionSort (actual); assertArrayEquals (expected, actual); } // method testSample
Insertion sort: public static void insertionSort (int[ ] x) { for (int i = 1; i < x.length; i++)
{ // At this point, x [0] <= x [1] <= … <= x [i-1].
SIFT x [i] DOWN TO ITS PROPER PLACE IN x [0], x [1], … x [i – 1]. } // for } // insertionSort
Example: 80, 60, 90, 75, 55, 90, …
80, 60, 90, 75, 55, 90, … 60, 80 (Sorted)
60, 80, 90, 75, 55, 90, … 60, 80, 90 (Sorted)
60, 80, 90, 75, 55, 90, … 60, 75, 80, 90 (Sorted)
60, 75, 80, 90, 55, 90, … 55, 60, 75, 80, 90 (Sorted)
55, 60, 75, 80, 90, 90, … 55, 60, 75, 80, 90, 90 (Sorted)
Sift x [i] down by comparing it to x [i-1], x [i-2], …, until the proper place for x [i] is found.
/** * Sorts a specified array of int values into ascending * order.
* The worstTime(n) is O(n * n). * * @param x – the array to be sorted. * */ public static void insertionSort (int[ ] x) { for (int i = 1; i < x.length; i++) for (int k = i; k > 0 && x [k - 1] > x [k]; k - -) swap (x, k, k -1); } // method insertionSort
EXAMPLE, STARTING WITH i = 3:
60, 80, 90, 75, 55, 90 // i = 3; k = 3; swap
60, 80, 75, 90, 55, 90 // i = 3; k = 2; swap
60, 75, 80, 90, 55, 90 // i = 3; k = 1; no swap
60, 75, 80, 90, 55, 90 // i = 4; k = 4; swap
60, 75, 80, 55, 90, 90 // i = 4; k = 3; swap
AND SO ON
Worst case: x in descending order Let n = x.length. Total number of outer-loop iterations
= n-1 Total number of inner-loop iterations
= 1 + 2 + … + n-1
n-1 1 + 2 + 3 + ... + n-2 + n-1 = i = n(n-1) / 2 i=1
worstTime(n) maximum number of loop iterations = n-1 + n (n-1) / 2 worstTime(n) is quadratic in n.
averageTime(n) average number of loop iterations n-1 + n (n-1) / 4 averageTime(n) is quadratic in n.
In general, to estimate worstTime(n) or averageTime(n) for a nested loop, count the total number of iterations of the inner loop.
Exercise: Determine the exact number of inner-loop iterations (= number of swaps) in applying Insertion Sort to the following array of int values: 96, 86, 76, 56, 66
What if we want a version of InsertionSort to sort an array of String elements into lexicographic order? public static void insertionSort (Object[ ] x) { for (int i = 1; i < x.length; i++) for (int k = i; k > 0 && x [k -1] > x [k]; k - -) swap (x, k, k -1); } // method insertionSort
What if we want a version of InsertionSort to sort an array of String elements into lexicographic order? Illegal! public static void insertionSort (Object[ ] x) { for (int i = 1; i < x.length; i++) for (int k = i; k > 0 && x [k -1] > x [k]; k - -) swap (x, k, k -1); } // method insertionSort
public static void insertionSort (Object[ ] x) { for (int i = 1; i < x.length; i++) for (int k = i; k > 0 && (((Comparable)x [k -1]).compareTo (x [k]) > 0);k- -) swap (x, k, k -1); } // method insertionSort
An example of a call to this method: insertionSort (words);
The Comparable interface is appropriate when you want the elements sorted by the “natural” ordering, for example, String objects in lexicographic order.
What if you want the elements sorted into an unnatural order? For example, Integer objects in decreasing order, or String objects sorted by the length of the string.
public interface Comparator<T> { /**
* Compares two specified elements. * * @param element1 – one of the elements. * @param element2 – the other element. * * @return a negative integer, 0, or a positive * integer, depending on whether element1 * is less than, equal to, or greater than * element2. */ int compare (T element1, T element2);
} // interface Comparator
For example, to sort an array intArray of Integer elements into decreasing order: public class Decreasing implements Comparator<Integer> { public int compare (Integer i, Integer k) { return k.compareTo (i); } // method compare } // class Decreasing
public static <T> void insertionSort (T[ ] x, Comparator<T> comp)
{ for (int i = 1; i < x.length; i++) for (int k = i; k > 0 &&
comp.compare (x [k -1], x [k]) > 0); k- -)
swap (x, k, k -1); } // method insertionSort
For an example of a call to this method: insertionSort (intArray, new Decreasing());
Now suppose you want to sort stringArray, an array of strings, in increasing order of the lengths of the strings, with lexicographic comparison of equal-length strings, so that “yes” < “here” < “true” < “maybe”
public class ByLength implements Comparator<String> {
/** * Compares two specified String objects * lexicographically if they have the same length, and
* otherwise returns the difference in their lengths. * * @param s1 – one of the specified String objects. * @param s2 – the other specified String object. * * @return s1.compareTo (s2) if s1 and s2 have the * same length; otherwise, return
* s1.length() – s2.length(). *
*/
public int compare (String s1, String s2) { int len1 = s1.length(), len2 = s2.length(); if (len1 == len2) return s1.compareTo (s2); return len1 – len2; } // method compare } // class ByLength
insertionSort (stringArray, new ByLength());
The insertionSort method is unchanged!
The Comparator interface allows you tocompare elements in a class any way youwant, even if you cannot modify the class.
For example, you cannot modify the Integeror String classes.
Exercise: Determine the ordering of “Yes”, “here”, “true”, “maybe”, and “yes” by the version of compare In the above ByLength class. Note: ‘Y’ < ‘y’.
How Fast Can We Sort?
Given n elements to be sorted, a decision tree is a binary tree in which each non-leaf represents a comparison between two elements and each leaf represents a sorted sequence of the n elements. Left branch: Yes
Right branch: No
Example: Apply Insertion Sort to a1, a2, a3. a1 <= a2? a2 <= a3? a1 <= a3? a1 a2 a3 a1 <= a3? a2 a1 a3 a2 <= a3? a1 a3 a2 a3 a1 a2 a2 a3 a1 a3 a2 a1
A decision tree has one leaf for eachpermutation of the n elements to be sorted.
The number of permutations of n distinctelements is ?
n!
So a decision tree to sort n elements musthave n! leaves.
By the Binary Tree Theorem, for any non-empty tree t, leaves(t) <= 2 height(t)
Since n! = leaves(t), we must have
n! <= 2 height (t)
which implies that log2(n!) <= height(t)
In the context of a decision tree, height(t)represents the maximum number ofcomparisons needed to sort the nelements.
So log2(n!) <= the maximum numberof comparisons to sort n elements.
Therefore,
worstTime(n) >= log2(n!)
By concept exercise 11.7,
log2(n!) >= n/2 log2(n/2)
Then worstTime(n) >= n/2 log2(n/2)
So worstTime(n) is (n log n) for any comparison-based sort. What can we say about averageTime(n)?
averageTime(n) >= average number of comparisons
= total number of comparisons / n!
In a decision tree, what is the total number ofcomparisons equal to?
Hint: The length of each path from the root to a leafequals the number of comparisons in that path.
The total number of comparisons is equalto the sum of all root-to-leaf path lengths.
E(t), the external path length of tree t, is the sum of all root-to-leaf path lengths in t. So the average number of comparisons is
E(t) / n!
The External Path Length Theorem states that if a binary tree t has k > 0 leaves, E(t) >= (k / 2)floor (log2(k))
In a decision tree, the number of leaves is n!. so, by the External Path Length Theorem, E(t) >= (n! / 2) floor (log2(n!))
Then we get the following: averageTime(n) >= average # comparisons = E(t) / n!
>= (n! / 2) floor (log2(n!)) / n! = (1 / 2) floor (log2(n!)) >= (1 / 4) (log2(n!)) >= (n / 8) (log2(n / 2))
For any comparison-based sort,averageTime(n) is (n log n).
Exercise: Suppose, for some comparison-based sort method, worstTime(n) is O(n log n). True or false: 1. averageTime(n) is linear logarithmic in
n. 2. averageTime(n) is O(n log n).
3. averageTime(n) is (n log n).
Fast Sorts
Merge Sort
Given an array x of objects, keep splitting into subarrays until the size of a subarray is less than 7. Apply Insertion Sort to that subarray and then merge the subarrays back together.
For example, suppose x.length = 25.
Here is an outline based on size:
25 Split
12 Split 13 Split 6 6 6 7 Split Ins.sort Ins.sort Ins.sort
3 4 Merge Ins.sort Ins.sort 12 Merge 7 Merge 13
Merge 25
To simplify the merging, we’ll use an auxiliary array. Suppose we want to merge two sorted subarrays of 5 elements each: 20 30 44 71 95 15 17 28 33 88 15, the smaller of the two, is copied to the auxiliary array and the right index is incremented:
20 30 44 71 95 15 17 28 33 88 15 (in the auxiliary array) 17, the smaller of the two, is appended to the auxiliary array and the right index is again incremented:
20 30 44 71 95 15 17 28 33 88
15 17 (in the auxiliary array)
20, the smaller of the two, is copied to the auxiliaryarray and the left index is incremented:
20 30 44 71 95 15 17 28 33 88
15 17 20 (in the auxiliary array)
28, the smaller of the two, is copied to the auxiliaryarray and the right index is incremented. And so on.
In the worst case, how many comparisons are needed to merge two sorted subarrays of k elements each?
/** * Sorts a specified array of objects according to the * compareTo method in the specified class of elements. * The worstTime(n) is O(n log n). * * @param a – the array of objects to be sorted. * */ public static void sort(Object[ ] a)
public static void sort(Object[ ] a) { Object aux[ ] = (Object[ ])a.clone(); mergeSort(aux, a, 0, a.length); }
/** * Sorts, by the Comparable interface, a specified range of a * specified array into the same range of another specified array. * The worstTime(k) is O(k log k), where k is the
* size of the subarray. *
* @param src – the specified array whose elements are to be * sorted into another specified array. * @param dest – the specified array whose subarray is to be
* sorted. * @param low: the smallest index in the range to be sorted.
* @param high: 1 + the largest index in the range to be * sorted. */ private static void mergeSort (Object src[ ], Object dest[ ], int low, int high)
aux 59 46 32 80 46 55 87 43 44 81
mergeSort (aux, a, 0, 10)
a 59 46 32 80 46 55 87 43 44 81
mergeSort (a, aux, 0, 5) mergeSort (a , aux, 5, 10) Insertion Sort Insertion Sort
aux 32 46 46 59 80 43 44 55 81 87
merge
a 32 43 44 46 46 55 59 80 81 87
aux 59 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 50
mergeSort (aux, a, 0, 20)
a 59 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 50
mergeSort (a, aux, 0, 10) mergeSort (a, aux, 10, 20)
aux 59 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 50
mergeSort mergeSort mergeSort mergeSort(aux, a, 0, 5) (aux, a, 5, 10) (aux, a, 10, 15) (aux, a, 15, 20) Insertion Sort Insertion Sort Insertion Sort Insertion Sort
a 32 46 46 59 80 43 44 55 81 87 12 17 75 80 95 16 33 40 50 61
a 32 46 46 59 80 43 44 55 81 87 12 17 75 80 95 16 33 40 50 61
merge merge
aux 32 43 44 46 46 55 59 80 81 84 12 16 17 33 40 50 61 75 80 95
merge
a 12 16 17 32 33 40 43 44 46 46 50 55 59 61 75 80 80 81 84 87 95
private static void mergeSort (Object src[ ], Object dest[ ], int low, int high)
{ int length = high – low; // Use Insertion Sort for small subarrays. if (length < 7) { for (int i = low; i < high; i++) for (int j = i; j >low &&
((Comparable)dest[j-1]).compareTo(dest[j]) > 0; j--) swap (dest, j, j-1); return; } // if length < 7
// Sort left and right halves of src into dest. int mid = (low + high) >> 1; mergeSort (dest, src, low, mid); mergeSort (dest, src, mid, high); // If left subarray less than right subarray, copy src to dest. if (((Comparable)src [mid-1]).compareTo (src [mid]) <= 0) { System.arraycopy (src, low, dest, low, length); return; } // Merge sorted subarrays in src into dest. for (int i = low, p = low, q = mid; i < high; i++) if (q>=high || (p<mid &&
((Comparable)src[p]).compareTo (src[q])<= 0)) dest [i] = src [p++]; else dest[i] = src[q++]; } // method mergeSort
max comparisons n
n / 2 n / 2
n / 4 n / 4 n / 4 n / 4
…
n / 4 n / 4 n / 4 n / 4 n
n / 2 n / 2 n
n n
For merge sort, worstTime(n) is O(n log n)
THERE FORE
averageTime(n) is linear-logarithmic in n.
Exercise: Show the steps, including the arguments in the calls to mergeSort, to merge sort the following:
aux 27 26 25 … 2 1 mergeSort (aux, a, 0, 27) a
Arrays.java also a version of Merge Sort that takes a Comparator parameter: public static <T> void sort(T[ ] a,Comparator<? super T> c)
An example of a call to this version: Arrays.sort (myArray, new ByLength());
Collections.java also has two versions of Merge Sort: One to sort List<T> in the natural order, and one to sort List<T> that has a second parameter of type Comparator. Collections.sort (myList); Collections.sort (myList, new Reverse());
/** * Sorts a into ascending order. * The worstTime(n) is O(n * n), and averageTime(n) is * O(n log n). */ public static void sort (int[ ] a) {
sort1(a, 0, a.length); } // method sort
Quick Sort
/**
* Sorts the array x, from index off (inclusive) to index
* off + len (exclusive), into ascending order.
*/
private static void sort1(int x[ ], int off, int len)
If len < 7, use insertion sort.
Otherwise, partition the array x about a pivot element into two sub-arrays.
After partitioning, each element in the left sub-array will be less than or equal to the pivot and each element in the right sub-array will be greater than or equal to the pivot.
For now take the pivot to be the median of the first, middle and last elements.
59 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 50 v = pivot = median of x [0], x [0 + 20 / 2], x [19]
= median of {59, 95, 50} = ?
In a loop, we will partition x into a left subarray of items <= v and a right subarray of items >= v. We then recursively call sort1 for the left and right subarrays. Here are the basic loop and calls:
int v = x[m]; // v is the pivot
int b = off, c = off + len - 1;while(true) {
while (x[b] < v) b++; while (x[c] > v) c--;
if (b > c) break;
swap(x, b++, c--);}if (c – off + 1 > 1)
sort1 (x, off, c - off + 1);if (off + len – b > 1)
sort1 (x, b, off + len - b);
59 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 50 b c Increment b (zero times) until x [b] >= 59; decrement c (zero times) until x [c] =< 59. Then swap x [b] with x [c] and bump b and c.
50 46 32 80 46 55 87 43 44 81 95 12 17 80 75 33 40 61 16 59 b c
50 46 32 16 46 55 87 43 44 81 95 12 17 80 75 33 40 61 80 59 b c
50 46 32 16 46 55 40 43 44 81 95 12 17 80 75 33 87 61 80 59 b c
50 46 32 16 46 55 40 43 44 33 95 12 17 80 75 81 87 61 80 59 b c
50 46 32 16 46 55 40 43 44 33 17 12 95 80 75 81 87 61 80 59 bc
50 46 32 16 46 55 40 43 44 33 17 12 95 80 75 81 87 61 80 59 c b c = 11 and b = 12 Every element in x [0 … 11] <=59 Every element in x [12 … 19] >= 59
So we now call:
sort1 (x, 0, 12);
sort1 (x, 12, 8);
For a refinement, elements equal to the pivotwill be moved to locations between c and b,so they are not involved in any furtherpartitioning.
During partitioning, elements equal to thepivot are stored at either end of the subarray,and then moved to the middle afterpartitioning.
int v = x[m];// Establish Invariant: v* (<v)* (>v)* v*int a = off, b = a, c = off + len - 1, d = c;while(true) {
while (b <= c && x[b] <= v) {if (x[b] == v)
swap(x, a++, b);b++;
} while (c >= b && x[c] >= v) {
if (x[c] == v) swap(x, c, d--);
c--; } if (b > c)
break; swap(x, b++, c--);
}
59 46 59 80 46 55 87 43 44 81 95 12 17 80 75 33 40 59 16 50 b c
59 59 46 50 46 55 16 43 44 40 33 12 17 80 75 95 81 80 87 59 c b
12 17 46 50 46 55 16 43 44 40 33 59 59 59 75 95 81 80 87 80
sort1 (x, 0, 11);sort1 (x, 14, 6);
For another refinement, suppose len, the size of the subarray to be sorted, is > 40.
To increase the likelihood that the pivot will be close to the median, split the subarray into 3 segments, and take the median of each segment. pivot = median of the 3 medians
For example, suppose we have len = 90. Then we split x up into subarrays x [0 … 29], x [30 … 59] and x [60 … 89].
element 55…87… 22 92…33…12 21…46…67 index 0 15 29 30 45 59 60 75 89
For example, suppose we have len = 90. Then we split x up into subarrays x [0 … 29], x [30 … 59] and x [60 … 89].
element 55…87… 22 92…33…12 21…46…67 index 0 15 29 30 45 59 60 75 89
55 33 46 46
For the estimate of averageTime(n) and worstTime(n), we can imagine that Quick Sort creates a binary search tree. The root of the tree is the pivot. After the first partitioning, the pivot of the left subarray becomes the root of the left subtree, and so on.
Suppose x = {0, 1, 2, 3, … 98, 99} Already in order! 50
25 75 12 38 63 88 6 19 32 44 57 69 82 94 Best-Case Partitioning
Best-Case Partitioning:
log2(n/7) levels; at most n comparisons per level
Total number of comparisons
<= n log2n
Average-Case Partitioning:
Average height of a binary search tree: logarithmic in n
log2(n/7) levels; at most n comparisons
per level
Total number of comparisons n log2n
The averageTime(n): linear logarithmic in n.
Worst-Case Partitioning?
Suppose x = {1, 2, . . . , 18, 0, 38, 19, 20, 21, . . . , 37}
37 # of comparisons
1 38 39
0 35 37
3 36 35 2 33 33
5 34 31
…
Worst-Case Partitioning: # of comparisons n + (n-2) + (n-4) + … + 8
n/2
= Σ (2i) 2 * (n/2 * (n/2 + 1) / 2) i=4 n2 / 4
The worstTime(n) is quadratic in n.
Exercise: Suppose x starts out as 10, 9, 8, 7, 6, 16, 17, 18, 19, 20, 5, 4, 3, 2, 1, 11, 12, 13, 14, 15 the median of x [0], x [10], x [19] = 10. Just before the first swap of x[b] and x[c], b = 5 and c = 14. After all swaps, what does x contain? Don’t forget to move the pivot to the middle. What are the recursive calls to Quick Sort: sort1 (x, ?, ?); sort1 (x, ?, ?);