数据结构-快速排序(优化版本)

快速排序的思想是划分交换排序,利用分治法策略把一个序列划分成两个子序列。

步骤:我们先找一个基准(pivot),在学习中通常会选择第一个数为基准数,先从右往左找第一个比基准数大的数,再从左往右找第一个比基准数小的数,满足(i<j),交换两个数,再把基准数和a[i]交换。
从此我们就把序列分成[l,i-1] 和 [i+1,r],把基准数归位。反复递归…就可以把整个序列排好序。

平均时间复杂度为O(n * log2 (n))

code:

void quicksort(int left,int right)
{
	int i,j,temp,t;
	if(left>right)
		return ;
	temp=a[left];
	i=left; 
	j=right;
	while(i!=j)
	{	
		while(i<j&&a[j]>=temp)
			j--;
		while(i<j&&a[i]<=temp)
			i++;
		if(i<j)
		{
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
	}
	a[left]=a[i];
	a[i]=temp;
	quicksort(left,i-1);
	quicksort(i+1,right);
	return ;
}

我们考虑下最坏时间复杂度
如果待排序的序列就是有序序列 1 2 3 4 5 6 7…
利用快排的算法排序,他的时间复杂度达到了O(n^2)。
解释:每次都选择第一个数为基准数,每次递归只会减少一个数,递归n-1次,
就是n +(n-1)+ (n-2)+ …+ 3 + 2 + 1 求和公式算出时间复杂度为O(n^2)。
数据加强了这个模板就过不去…
比如这个题 快速排序

那我们怎么办呢?

其实很简单,我们只需要把基准数换一下,
换成序列中间的数为基准数就可以满足最坏时间复杂度为O(n * log2 (n))
步骤就是我们每次选取中间的数为基准数(选取基准数为a[(l+r)>>1]),从左往右找比基准数大的,从右往左找比基准数小的,满足条件就交换。这样就把一个序列分成了[l,j] 和 [j+1,r] (a[j]就是分界点,左边(包括a[j])都比基准数小,右边都比基准数大 ) ,当然你选择[l,i-1] 和 [i,r]也是可以(选取基准数为a[(l+r+1)>>1])。

code:

void quicksort(ll l,ll r)
{
	ll i,j,temp;
	if(l>=r)
		return;
	temp=a[l+r>>1];
	i=l-1,j=r+1;
	while(i<j)
	{
		while(a[++i]<temp) ;
		while(a[--j]>temp) ;
		if(i<j) swap(a[i],a[j]);
	}
	quicksort(l,j);  //a[j]就是分界点,左边都比基准数小,右边都比基准数大 
	quicksort(j+1,r);
} 
发布了88 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43667611/article/details/104015747
今日推荐