對一個東西,首先要講他的利與弊,才知道怎麼使用它。快速排序適用於各類不一樣的輸入數據且在通常應用中比其餘排序都要快得多。快速排序引人注目的特色包括它是原地排序(只須要一個很小的輔助棧),且長度爲N的數組排序所需的時間和NlgN成正比。它的主要缺點是很是脆弱,在實現時要很是當心才能避免低劣的性能。java
有了對比,才能知道它的好處。其實快速排序是一種分治的排序算法。它將一個數組分紅兩個子數組,將兩部分獨立地排序。講到這裏,有人就會有個疑問,那不是和歸併排序同樣嗎?合併排序也是分治算法的一種,也是將一個數組分紅兩個子數組。快速排序和歸併排序時互補的:歸併排序將數組分紅兩個子數組分別排序,並將有序的子數組歸併以整個數組排序;而快速排序將數組排序的方式則是當兩個數組都有序時整個數組也就天然有序了。在第一種狀況下,遞歸調用發生在處理整個數組以前;在第二種狀況下,遞歸調用發生在處理整個數組以後。在歸併排序中,一個數組被等分爲兩半;在快速排序中,切分的位置取決於數組的內容。這句話最重要。算法
public class Quick{ public static void sort(Comparable[] a){ StdRandom.shuffle(a);//消除對輸入的依賴,直接生成隨機數 sort(a,0,a.length-1); } private static void sort(Comparable[] a, int lo, int hi){ if(hi <= lo) return; int j= partition(a,lo,hi);//切分 sort(a,lo,j-1); sort(a,j+1,hi); } private static int partition(Comparable[] a, int lo ,int hi){ int i = io,j=hi+1; Comparable v = a[lo]; while(true){ while(less(a[++i],v)) if(i==hi) break; while(less(v,a[--j])) if(j==lo) break; if(i>=j) break; exch(a,i,j) } exch(a,lo,j); return j; } private static void exch(Comparable[] a ,int i ,int j){ Comparable t = a[i];a[i]=a[j];a[j]=t; } private static boolean less(Comparable v , Comparable w){ return v.compareTo(w)<0; } }