快速排序普通法与中值枢纽元法以及三切法

快速排序影响速度的一个因素便是枢纽元,在这里第一种方法为将第一个元素作为枢纽元,这样做有一个弊端,就是当顺序为逆序时或者大量重复的数时T(N) = O(N^2),方法一是中值枢纽法,即将第一个,中间的,和最后一个取中值,并将他们放在合适的位置,然后递归,这里有一点与普通法不同,i=left,j=right -1(中值法);i = left,j=right+1(普通法)且在最后的交换也不同!还有一点要注意----递增i和j时必须用前自增,如果用后自增,后面交换的值便是当前值得下面的值,这点需要注意,还有就是边界检查,中值法并不需要,因为将中值放在right-1处,a[i]不会大于中值,且a[j]不会小于i!

下面是对比代码:

<span style="font-size:14px;">package 排序;

import java.util.Arrays;

public class Qsort {
	
	private final static int CUTOFF = 10; 
	/*
	 * normal way
	 */
	/*public static void qSort(int[] a,int left,int right){
		//if(left + CUTOFF >= right) insertion(a,left,right);//optimize with insertion sort
		//else{
			if(left >= right) return;
			//int p = median3(a,left,right);
			//System.out.println(p);
			int p = a[left];
			int i = left,j = right + 1;//set head pointer and tail pointer
			while(true){
				while(i!=right&&a[++i] < p){}
				while(j!=left&&a[--j] > p){}
				if(i<j) 
					swap(a,i,j);
				else 
					break;
			}
			swap(a,left,j);//put the pivot in the right pos
			
			qSort(a,left,j-1);
			qSort(a,j+1,right);
		//}
	}*/
	
	
	/*
	 * median way
	 */
	public static void qSort(double[] a,int left,int right){
		if(left + CUTOFF >= right) insertion(a,left,right);//optimize with insertion sort
		else{
			//System.out.println("processing");
			if(left >= right) return;
			double p = median3(a,left,right);
			//System.out.println(p);
			int i = left,j = right + 1;//set head pointer and tail pointer
			while(true){
				while(a[++i] < p){}
				while(a[--j] > p){}
				if(i<j) 
					swap(a,i,j);
				else 
					break;
			}
			swap(a,right-1,i);//put the pivot in the right pos
			qSort(a,left,i-1);
			qSort(a,i+1,right);
		}
	}
	public static double median3(double[] a,int lo,int hi){
		int mid = (lo+hi)/2;
		if(a[lo] > a[mid]) swap(a,lo,mid);
		if(a[lo] > a[hi] ) swap(a,lo,hi);
		if(a[mid] > a[hi]) swap(a,mid,hi);
		swap(a,mid,hi-1);//hide pivot
		return a[hi-1];//return pivot
	}
	public static void swap(double[] a,int i,int j){
		double temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
	public static void insertion(double[] a,int lo,int hi){
		//System.out.println(lo);
		for(int i=lo;i<=hi;i++){
			for(int j=i;j>0&&a[j]<a[j-1];j--){
				swap(a,j,j-1);
			}
		}
	}
	public static void main (String[] args){
		double a[] = new double[100000];//data
		for(int i=0;i<a.length;i++){
				a[i] = (double)Math.random()*100000;
		}

		qSort(a,0,a.length-1);
		long after = System.currentTimeMillis(); 
		System.out.println(Arrays.toString(a));
	}
}
</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值