快速排序

与前面归并排序不同的另一种分治策略----快速排序
与归并排序不同的是:快排不要求分成相等的两半、归并主要是合并,快排主要是划分、归并有一个辅助数组,快排不要。
java类库中的快排:java.until中的Arrays使用快排对基本类型的数组按升序排序。方法:

public static void sort(type[] a);
public static void sort(type[] a,int first,int last);

 

 快速排序的思想:先在序列中找到一个支点,使支点左边元素小于等于支点元素,右边元素大于等于支点元素(称为划分)。然后再对左右两部分执行同样的划分。

创建划分步骤:在选定支点之后,将它与最后一个元素相交换,使得再创建划分时支点不成为障碍。从第一个元素开始向后寻找第一个大于或等于支点的节点1,再从倒数第二个元素开始向前寻找第一个小于或等于支点的节点2,如果节点1小于节点2则交换节点1、2。继续做这样的寻找交换,直到最后一次完成,将最后一次不小于支点的元素与支点交换,划分完成。

快速排序图解:(图解1,使用的是选取第一个元素为支点)

 

支点的选择:最好的情况,支点就是序列的中值,致使划分后两部分近似相等。完全达到这种情况时浪费时间的,近似达到的方法是三者取中值支点法将数组中第一个元素和中间一个元素以及最后一个元素的中值作为支点(先排序三个元素,取第二个就是)。

调整划分算法:三者取中值法处理之后,第一个元素和最后一个元素,分别小于大于支点元素,因此不要对其执行划分,划分算法中先将中间元素与last-1处元素交换,从左右开始查找的步骤只需要分别从first+1、last-2处进行。因为有第一个元素小于支点,最后一个元素大于支点的限制,再寻找的过程中没有必要考虑数组越界的界限。

快速排序源代码:

public class Quick_Sort {
	static int MIN_SIZE=3;//由于快排判断考虑的是多余三个元素的序列,必须大于等于3
	private static<T extends Comparable<?super T>>
	void sortFirstMiddleLast(T[] a,int first,int mid,int last){
		order(a,first,mid);
		order(a,mid,last);
		order(a,first,mid);
	}
	private static<T extends Comparable<?super T>>
	void order(T[] a,int i,int j){
		if(a[i].compareTo(a[j])>0){
			swap(a,i,j);
		}
	}
	private static void swap(Object[] array,int i,int j){
		Object temp=array[i];
		array[i]=array[j];
		array[j]=temp;
	}
	private static<T extends Comparable<?super T>>
	int partition(T[] a,int first,int last){
		int mid=(first+last)/2;
		sortFirstMiddleLast(a,first,mid,last);
		swap(a,mid,last-1);
		int pivotIndex=last-1;
		T pivot=a[pivotIndex];
		int indexFromLeft=first+1;
		int indexFromRight=last-2;
		boolean done=false;
		while(!done){
			while(a[indexFromLeft].compareTo(pivot)<0){
				indexFromLeft++;
			}
			while(a[indexFromRight].compareTo(pivot)>0){
				indexFromRight--;
			}
			assert a[indexFromLeft].compareTo(pivot)>=0&&a[indexFromRight].compareTo(pivot)<=0;
			if(indexFromLeft<indexFromRight){
				swap(a,indexFromLeft,indexFromRight);
				indexFromLeft++;
				indexFromRight--;
			}else{
				done=true;
			}
		}
		swap(a,pivotIndex,indexFromLeft);
		pivotIndex=indexFromLeft;
		return pivotIndex;
	}
	public static<T extends Comparable<?super T>>
	void quickSort(T[] a,int first,int last){
		if(last-first+1<MIN_SIZE){//此时执行插入排序
			Insert_Sort.insertionSort(a,first,last);
		}else{//此时执行快速排序
			int pivotIndex=partition(a,first,last);
			quickSort(a,first,pivotIndex-1);
			quickSort(a,pivotIndex+1,last);
		}
	}
}

时间复杂度:O(n*lgn)最坏是n^2

空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值