chapter 11 sorting. selection sort 0 1 n-2 n-1index 2 4 1 3 第 0 回合 第 1 回合 2 4 13 2 4 31...

Post on 18-Dec-2015

219 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

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, ?, ?);

top related