面试总结: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 }
View Code

 

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:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/dce0192fe4e3d551c72c7753e2da74df74987c27/sort/QuickSort.java

 

你可能感兴趣的:(Quicksort)