快速排序的改进

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;
		}		
	}	
}

 

posted @ 2017-10-25 12:37  佟学强  阅读(1068)  评论(0编辑  收藏  举报