快速排序

快速排序

快速排序的三个步骤:

这里最重要的就是如何调整区间?

朴素做法:

我们开两个数组a[]、b[],然后把q[]数组都扫一遍。

如果大于等于分界点x,放在a[]里。否则放在b[]里。

最后,把a[]、b[]都放回q[]。

优美做法:

1.选择一个分界点x = q[l] q[r] q[l + r >> 1] (注意不要取q[l] q[r]会TLE,acwing数据加强了)

2.取两个指针i、j在l、r的两侧。即i = l-1,j = r+1。

每次i++,判断q[i]<x满足则前往下一个,否则就停止。

每次j--,判断q[j]>=x满足则前往下一个,否则就停止。

判断i < j,则交换q[i]、q[j]。

3.递归左右两段。

如果选择i分段,则x != q[l].

如果选择j分段,则x != q[r].

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 100010;

int n;
int q[N];

void quick_sort(int q[],int l,int r)
{
	if (l >= r) return;
	
	int x = q[(l+r)/2],i = l - 1,j = r + 1;
	//x分界点任意取l、r、mid
	//i、j指针指向的是边界的两侧
	while (i < j)
	{
		do i ++ ;while (q[i] < x);
		do j -- ;while (q[j] > x);
		if (i < j) swap(q[i],q[j]);
	}
	//递归循环分好的两区间用
	//i划分:l,i-1 i,r 但是x不能用q[l]死循环 
	quick_sort(q,l,j);
	quick_sort(q,j+1,r);
	
}
int main(){
	scanf("%d",&n);
	for (int i = 0; i < n; i ++ ) scanf("%d",&q[i]);
	
	quick_sort(q,0,n-1);
	
	for (int i = 0; i < n; i ++ ) printf("%d ",q[i]);	
    return 0;
}

时间复杂度

每层都要扫一遍即n次,每次取分界点期望在n/2,到把n除到1,大约需要递归logn次。

平均时间复杂度nlogn,最坏时间复杂度n^2.

posted @ 2021-04-10 11:13  Treasure_lee  阅读(52)  评论(0编辑  收藏  举报