快速排序

快速排序的思想在于将每个数归位于自己应该在的位置。

递归版本:

#include<iostream>
void swapp(int &tmp1,int &tmp2);
int partition(int *tmp,int left,int right) ;
void quicksort(int *tmp,int left,int right){
	if(left<right){
		int pos = partition(tmp,left,right);
		quicksort(tmp,left,pos-1);
		quicksort(tmp,pos+1,right);
	}
}
int partition(int *tmp,int left,int right) {
	int i=left+1,j=right;
	int p=tmp[left];
	while(i<j){
		while(i<=j&&tmp[i]<=p)++i;
		while(i<=j&&tmp[j]>=p)--j;
		swapp(tmp[i],tmp[j]);
	}	
	swapp(tmp[i],tmp[j]);
	if(tmp[left]>tmp[j])swapp(tmp[left],tmp[j]);
	return j;
}
void swapp(int &tmp1,int &tmp2){	
	if(tmp1!=tmp2){
		int p;
		p = tmp1;
		tmp1 = tmp2;
		tmp2 = p;
	}
}
int main(){
	using namespace std;
	int A[]={5,3,1,9,8,2,4,7},size;
	size = sizeof(A)/sizeof(*A);
	quicksort(A,0,size-1);
	for(int i=0;i<size;++i)
		cout<<A[i]<<" ";
	cout<<endl;
}
这种从两端开始进行比较的方法,判定界限不易划分,实现起来不是很轻松。
先进行时间复杂度分析,然后再看看改进版本。
公式粘贴不上来,只能插入图片了,各位看官将就一下。

根据master定理,最好情况下


而在最坏情况下,所有的分裂点都趋于极端也就是说这个序列本身已经排好序了,比如说目标序列是一个降序排列的序列,现在想得到它的升序排列。
第一次分裂     需要比较的次数为:n+1次
第二次分裂     需要比较的次数为: n 次
第三次分裂     需要比较的次数为:n-1次
.........
第n-1次分裂    需要比较的次数为: 3 次
所以最坏情况下时间复杂度为:


快速排序的时间复杂度被认为是N^2。
快速排序有好几个改进版本,下面只是其中一个。
其改进版本也只能说思想上是一样的,但具体的实现形式可能会不同。

#include<iostream>
void swapp(int &tmp1,int &tmp2);
int partition(int *tmp,int left,int right) ;
void quicksort(int *tmp,int left,int right){
	if(left<right){
		int pos = partition(tmp,left,right);
		quicksort(tmp,left,pos-1);
		quicksort(tmp,pos+1,right);
	}
}
int partition(int *tmp,int left,int right) {
	int i=left,j=left+1;
	int p=tmp[left];
	while(j<=right){
		if(tmp[j]<p){
			++i;
			swapp(tmp[i],tmp[j]);
		}
		++j;
	}
	swapp(tmp[left],tmp[i]);
	return i;
}
void swapp(int &tmp1,int &tmp2){	
	if(tmp1!=tmp2){
		int p;
		p = tmp1;
		tmp1 = tmp2;
		tmp2 = p;
	}
}
int main(){
	using namespace std;
	int A[]={5,3,1,9,8,2,4,7},size;
	size = sizeof(A)/sizeof(*A);
	quicksort(A,0,size-1);
	for(int i=0;i<size;++i)
		cout<<A[i]<<" ";
	cout<<endl;
}

每次比较都从一端开始,实现起来轻松许多。

对于快速排序,稍加修改可以很容易的获取排在第k个位置上或者说第k大小的数据,只需要在获取pos的值以后加一个比较。

若pos>k     选取左端数据进入迭代;

若pos<k     选取右端数据进入迭代;

若pos=k     得到所要查找的数据。

该算法的效率在平均情况下是线性的,然而最坏情况下又退化到了n^2的数量级。

这里并没有具体讨论此方法获取第k个位置的数据时间复杂度的计算方法,有此需要的朋友,大家可以一块儿讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值