面试总结:QuickSort 解析
Quick Sort
http://en.wikipedia.org/wiki/Quicksort
Quicksort, or partition-exchange sort, is a sorting algorithm developed by Tony Hoarethat, on average, makes O(n log n) comparisons to sort n items. In the worst case, it makes O(n2) comparisons, though this behavior is rare. Quicksort is often faster in practice than other O(n log n) algorithms.[1] Additionally, quicksort's sequential and localized memory references work well with a cache. Quicksort is a comparison sort and, in efficient implementations, is not a stable sort. Quicksort can be implemented with an in-place partitioning algorithm, so the entire sort can be done with only O(log n) additional space used by the stack during the recursion.[2]
1. 平均复杂度:O(nLogn)
1 package Algorithms.sort; 2 3 /********************************************************* 4 * 5 * 08-722 Data Structures for Application Programmers 6 * Lab 5 Comparing MergeSort with QuickSort 7 * 8 * A simple QuickSort implementation 9 * 10 *********************************************************/ 11 12 import java.util.*; 13 14 public class QuickSort { 15 //private static final int SIZE = 100000; 16 private static final int SIZE = 10000; 17 private static Random rand = new Random(); 18 19 public static void main(String args[]) { 20 int[] array = new int[SIZE]; 21 22 for (int i = 0; i < SIZE; i++) 23 //array[i] = rand.nextInt(); 24 array[i] = i; 25 26 //int[] array = {3, 4, 6, 1, 7, 8, 6}; 27 28 // reversely ordered 29 /* 30 for(int i=0;i<SIZE; i++) array[i] = SIZE - i; 31 */ 32 33 quickSort(array); 34 35 // to make sure sorting works. 36 // add "-ea" vm argument 37 assert isSorted(array); 38 39 System.out.println(isSorted(array)); 40 //printArray(array); 41 } 42 43 public static void printArray(int[] arr) { 44 System.out.println(); 45 for(int i: arr) { 46 System.out.println(i + " "); 47 } 48 } 49 50 public static void quickSort(int[] arr) { 51 recQuickSort(arr, 0, arr.length - 1); 52 } 53 54 private static void recQuickSort(int[] arr, int left, int right) { 55 // Just the input parameter. 56 if (arr == null || left >= right) { 57 return; 58 } 59 60 // we just set the right node to be pivot. 61 int pivPosition = partition(arr, left, right, arr[right]); 62 63 recQuickSort(arr, left, pivPosition - 1); 64 recQuickSort(arr, pivPosition + 1, right); 65 } 66 67 // partition the array and return the new pivot position. 68 private static int partition(int[] arr, int left, int right, int pivot) { 69 // set the pivot. 70 int l = left - 1 ; 71 int r = right; 72 73 /* 74 example: 75 let 6 to be the pivot. 76 77 (1) At the beginning: 78 3 4 6 1 7 8 6 79 l r 80 81 82 (2) After the first while loop: 83 3 4 6 1 7 8 6 84 l r 85 86 (3) swap them, then continue to move i and j: 87 3 4 1 6 7 8 6 88 l r 89 90 (3) swap them, then continue to move i and j: 91 3 4 1 6 7 8 6 92 l pivot 93 r 94 (4) swap the left and the pivot. 95 3 4 1 6 7 8 6 96 l pivot 97 98 */ 99 100 while (true) { 101 // Find the first element which does not fulfill the rule 102 // It will not move out of range because the right node is pivot. 103 // 使用< 很重要,这样可以避免l跑到pivot的位置,就是right的位置 104 //while (l < r && arr[++l] <= pivot); 105 while (arr[++l] < pivot); 106 107 // Find the first element which does not fulfill the rule 108 // Don't need to move r to be left of LEFT. 109 while (r > l && arr[--r] > pivot); 110 111 // If r <= l, means that all the elements is in the right place. 112 if (r <= l) { 113 break; 114 } 115 116 // Swap the first two elements that does not fit the rule. 117 swap(arr, r, l); 118 } 119 120 // The l pointer point to the first element which is bigger than the pivot. 121 // So we can put the pivot just here. Because put a big or equal one in the last will not change the rule that: 122 // all the smaller one is in the left and the right one is in the right. 123 swap(arr, l, right); 124 125 return l; 126 } 127 128 // private helper method to swap two values in an array 129 private static void swap(int[] arr, int dex1, int dex2) { 130 int tmp = arr[dex1]; 131 arr[dex1] = arr[dex2]; 132 arr[dex2] = tmp; 133 } 134 135 /********************************************************** 136 * Check if array is sorted. A simple debugging tool 137 **********************************************************/ 138 private static boolean isSorted(int[] array) { 139 return isSorted(array, 0, array.length - 1); 140 } 141 142 private static boolean isSorted(int[] array, int lo, int hi) { 143 for (int i = lo + 1; i <= hi; i++) 144 if (array[i] < array[i - 1]) 145 return false; 146 return true; 147 } 148 149 }
2. Worst case: O(n^2)
以下代码展示了一个worst case:
当数列是有序,并且每次选择最右边的值,那么quicksort退化为O(n^2)的复杂度:
TEST CASE:
RESULT(因为递归层数太多直接导致Stack over flow):
3. 稳定性
QuickSort并不稳定
http://bbs.csdn.net/topics/60524397
证明去Quick Sort是不稳定的,只需举出其不是稳定的例子即可。
例:
待排序数组: int a[] ={1, 2, 2, 3, 4, 5, 6};
在快速排序的随机选择比较子阶段,若选择a[2]为比较子,即数组中的第二个2,而把大于等于比较子的数均放置在大数数组中,则a[1],即数组中的第一个2。那么数组中的两个2非原序。
若选择a[1]为比较子,而把小于等于比较子的数均放置在小数数组中,则数组中的两个2顺序也非原序
这就说明,Quick Sort是不稳定的。
4. GITHUB:
posted on 2014-12-20 12:43 Yu's Garden 阅读(1481) 评论(0) 编辑 收藏 举报