这一个算是一个比较完善的快速排序了吧,就是代码多了点,没办法,要想性能好,考虑的东西就得多点。
package sort; public class QuickSort { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int n = 10000000; int[] arr = new int[n]; for (int i = n; i > 0; i--) { arr[i - 1] = i; } QuickSort q = new QuickSort(arr); long now = System.currentTimeMillis(); q.sort(); System.out.println("time="+(System.currentTimeMillis() - now)); //q.display(); } private int[] arr; public QuickSort(int[] arr){ this.arr = arr; } public void display(){ for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } public void sort(){ recQuickSort(0,arr.length - 1); } private void recQuickSort(int left,int right){ int size = right - left + 1; if(size < 10){ //小于10的小数组可以用插入排序,比较省事 insertSort(left,right); }else{ int maddie = getMiddleValue(left,right); //获取最平均的枢纽值 int partition = partitionIt(left,right,maddie); recQuickSort(left,partition - 1); recQuickSort(partition + 1,right); } } /**将指定范围内的数据用枢纽值切割成两个部分, * 枢纽值做为分界,在枢纽值左边的全部小于它,右边全部大于它 * @param left 左边索引 * @param right 右边索引 * @param privot 枢纽值 * @return */ private int partitionIt( int left, int right, int privot) { int leftPtr = left; int rightPtr = right - 1; while(true){ //左边第二个数据(第一个数据已经在getMiddleValue方法里排好序,肯定比枢纽值小)和枢纽值比较,碰到小于枢纽值的数据停止比较 while(arr[++leftPtr] < privot); //右边第三个数据和枢纽值比较(右边第一个在getMiddleValue方法里排序肯定比枢纽值大,第二个是枢纽值本身,都不用比较) while(arr[--rightPtr] > privot); //指针交叉停止比较 if(leftPtr >= rightPtr){ break; }else{ //将左边小于枢纽值的数据和右边大于枢纽值的数据交换 swap(leftPtr,rightPtr); } } //将枢纽值放到边界处(此时该枢纽值已经处于最终排序的位置,也就是说它不需要再移动了) swap(leftPtr,right - 1); return leftPtr; } /**获取比较平均的枢纽值(这在逆序的情况下很有用) * 分别取最左,中间,最右三个值,取当中的中间值作为枢纽值,并对它们排序 * @param left * @param right * @return */ private int getMiddleValue( int left, int right) { int middle = (left + right)/2; if(arr[left] > arr[middle]) swap(left,middle); if(arr[left] > arr[right]) swap(left,right); if(arr[middle] > arr[right]) swap(middle,right); //中间值和最右边倒数第二个值交换,这样的话最右边和其左边第一个都不用参加和枢纽值的比较,因为他们是大于等于的。 swap(middle,right - 1); return arr[right - 1]; } /**交换元素 * @param a * @param b */ private void swap(int a,int b){ int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } /**插入排序 * @param left * @param right */ private void insertSort(int left,int right){ int out,inner,temp; for (out = left + 1 ; out < right; out++) { temp = arr[out]; inner = out; while(inner > left && arr[inner - 1] >= temp){ arr[inner] = arr[inner - 1]; inner--; } arr[inner] = temp; } } }100w逆序排序耗时28毫秒。比希尔快一点哦。付出的是复杂的算法和大量的代码。看如何取舍咯。