递归版 public class Quick { private static final int carry = 15; public static void sort(Comparable[] a){ quick(a,0,a.length-1); } public static void quick(Comparable[] a,int lo,int hi){ if(hi<=lo) return ; /* * * 子数组长度小于15使用插入排序 * */ if(hi-lo<carry) { insertsort(a, lo, hi); return; } int i=partion(a,lo,hi); quick(a,lo,i-1); quick(a,i+1,hi); } /* * 插入排序 * */ public static void insertsort(Comparable[] a,int lo,int hi){ for (int i = lo; i <=hi; i++) { for (int j = i; j >lo&&less(a[j],a[j-1]) ; j--) exch(a,j,j-1); } } /* * 找到第x小的数组 * 迭代 * */ public static Comparable select(Comparable[] a,int k){ int lo=0,hi=a.length-1; while (lo<hi){ int mid=partion(a,lo,hi); if(mid<k) lo=mid+1; else if(mid>k) hi=mid-1; else return a[mid]; } return null; } /* * 版本一 * * * public static int partion(Comparable[] a,int lo,int hi){ int i=lo,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; } */ /* * 改良点二 * 改动哨兵 * */ public static int partion(Comparable[] a,int lo,int hi){ int m=media3(a,lo,(lo+hi)/2,hi); exch(a,lo,m); int i=lo,j=hi+1; Comparable v=a[lo]; while (true){ while (less(a[++i],v)) if(i==hi) break; /* * 由于 a[lo] 最后才移动二v==a[lo] 所以最终 j>=lo; * */ while (less(v,a[--j])) ; if(i>=j) break; exch(a,i,j); } exch(a,lo,j); return j; } /* * 改良点三 * 取中位数 * * */ public static int media3(Comparable[]a,int i,int k,int j){ return (less(a[i], a[j]) ? (less(a[j], a[k]) ? j : less(a[i], a[k]) ? k : i) : (less(a[k], a[j]) ? j : less(a[k], a[i]) ? k : i)); } private static boolean less(Comparable v,Comparable w){ return v.compareTo(w)<0; } private static void exch(Comparable[] a,int i,int j){ Comparable t=a[i];a[i]=a[j];a[j]=t; } public static boolean isSorted(Comparable[] a){ for (int i = 0; i <a.length ; i++) { if(less(a[i],a[i])) return false; } return true; } public static void main(String[] args){ Comparable a[]={1,4,5,6,7,8,9,0,3,2}; sort(a); for (int i = 0; i <a.length ; i++) { System.out.println(a[i]); } } }
非递归版
import java.util.Stack; public class QuickfindX { private static final int carry = 15; public static void sort(Comparable[] a){ quick(a,0,a.length-1); } public static void quick(Comparable[] a,int lo,int hi){ if(hi<=lo) return ; Stack<Integer> st=new Stack<Integer>(); if(lo<hi){ //依次将[mid+1,hi],[lo,mid-1]压入栈底 int i=partion(a,lo,hi); if(hi>i+1){ st.push(i+1); st.push(hi); } if(lo<i-1){ st.push(lo); st.push(i-1); } while(!st.empty()){ int histak=st.pop(); int lostak=st.pop(); int mid=partion(a,lostak,histak); if(less(mid+1,histak)){ st.push(mid+1); st.push(histak); } if(less(lostak,mid-1)){ st.push(lostak); st.push(mid-1); } } } } public static void insertsort(Comparable[] a,int lo,int hi){ for (int i = lo; i <=hi; i++) { for (int j = i; j >lo&&less(a[j],a[j-1]) ; j--) exch(a,j,j-1); } } public static int partion(Comparable[] a,int lo,int hi){ int i=lo,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 boolean less(Comparable v,Comparable w){ return v.compareTo(w)<0; } private static void exch(Comparable[] a,int i,int j){ Comparable t=a[i];a[i]=a[j];a[j]=t; } public static boolean isSorted(Comparable[] a){ for (int i = 0; i <a.length ; i++) { if(less(a[i],a[i])) return false; } return true; } public static void main(String[] args){ Comparable a[]={1,4,5,6,7,8,9,0,3,2}; sort(a); for (int i = 0; i <a.length ; i++) { System.out.println(a[i]); } } }
三向快排 Array.sort() 默认两种实现 三向快排 和归并排序
解决了因为 数组中含有大量重复数据时候普通快速排序性能急剧下降的问题
a[lo,lt-1] <v
a[lt,i-1]=v
a[i,gt]>v
a[lt]<v,将a[lt]和a[i]交换,将lt和i加一
a[lt]>v,将a[gt]和a[i]交换,将gt减一
a[lt]=v,将i加一
public class QuickThree { public static void sort(Comparable[] a){ quick(a,0,a.length-1); } public static void quick(Comparable[] a,int lo,int hi){ if(hi<=lo) return ; int lt=lo,gt=hi,i=lo+1; Comparable v=a[lo]; while (i<=gt){ int cmp=a[i].compareTo(v); if(cmp<0) exch(a,lt++,i++); else if(cmp>0) exch(a,gt--,i); else i++; } quick(a,lo,lt-1); quick(a,gt+1,hi); } private static void exch(Comparable[] a,int i,int j){ Comparable t=a[i];a[i]=a[j];a[j]=t; } public static void main(String[] args){ Comparable a[]={1,4,5,6,7,8,9,0,3,2}; sort(a); for (int i = 0; i <a.length ; i++) { System.out.println(a[i]); } } }