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

 

posted on 2014-12-20 12:43  Yu's Garden  阅读(1481)  评论(0编辑  收藏  举报

导航