快速排序的改进
package com.txq.test; /** * quicksort,三方面改进:①三数中值选择枢纽元②容量小的时候使用插入排序③重复元素的处理 * @author XueQiang Tong * @date 2017/10/25 */ public class QS { public void quicksort(int []arr,int low,int high){ int first = low; int last = high; int left = low; int right = high; int leftLen = 0; int rightLen = 0; //当分割后的容量较小时,使用插入排序,提高性能 if(high - low + 1 <= 10){ InsertSort(arr,low,high); return; } int key = SelectPivotMedianOfThree(arr,low,high); while(low < high){ while(high > low && arr[high] >= key){ if(arr[high] == key){//重复元素处理策略:分割过程中把他们放在数组两端,递归调用时掠过他们,提高性能 swap(arr,high,right); right --; rightLen ++; } high --; } arr[low] = arr[high];//交换 while(high > low && arr[low] <= key){ if(arr[low] == key){ swap(arr,low,left); left ++; leftLen ++; } low ++; } arr[high] = arr[low];//交换 } arr[low] = key;//此时总是low = high,把key放在此位置,一次迭代完成,进入下次递归调用 //接下来,把重复元素存储到key的周围 int i = low - 1; int j = first; while(j < left && arr[i] != key){ swap(arr,j,i); i --; j ++; } i = low + 1; j = last; while(j > right && arr[i] != key){ swap(arr,j,i); i ++; j --; } quicksort(arr,first,low - leftLen - 1); quicksort(arr,low + rightLen + 1,last); } /** * low,mid,high,对三个数排序,arr[mid] <= arr[low] <= arr[high],取arr[low]作为枢纽元 * @param arr * @param low * @param high * @return */ private int SelectPivotMedianOfThree(int[] arr, int low, int high) { int mid = low + ((high - low) >> 1); if(arr[mid] > arr[high]){ swap(arr,mid,high); } if(arr[low] > arr[high]){ swap(arr,low,high); } if(arr[low] < arr[mid]){ swap(arr,low,mid); } return arr[low]; } public void swap(int arr[],int i, int j) { int tmp; tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } /** * 插入排序 * @param arr */ private void InsertSort(int[] arr,int low,int high) { int i,j; int n = high - low + 1; int target; for(i = low+1;i < low+n;i++){ j = i; target = arr[i]; while(j > low && target < arr[j-1]){ arr[j] = arr[j-1]; j--; } arr[j] = target; } } }