利用快速排序算法将读入的 N个数从小到大排序后输出,请勿使用std::sort。
输入格式
第一行一个整数 n
第二行 n 个整数
输出格式
输出一行,为 ai 排序后的结果。
Sample
1Input
5
4 7 1 4 6
Output
1 4 4 6 7我们已经遇到好多排序题了,并且掌握了好多种排序方法,像比较常见的比较排序,桶排序,冒泡排序,但是这几种方法的时间复杂度O(M+N)或者O(N*N),这是一个非常高的时间复杂度,如果用这几种方法会时间超限,接下来的快速排序就能在一定程度上解决这个问题。
下面说一下具体排序过程:
首先我们先要设定一个基准数,通过基准数将数组a分成两个部分为接下来的排序做准备。
接下来将大于或等于基准数的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于基准数,而右边部分中各元素都大于或等于基准数。
然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以再取一个基准数,将该部分数据再分成左右两部分,继续模拟刚才的过程在左边放置较小值,右边放置较大值。右侧的数组数据也做同样的处理。
最后通过递归将左侧部分排好序后,再递归排好右侧部分的顺序,直到整个数组的排序完成。这种排序之所以快的原因是它每次的排序都是跳跃式的。
#include<stdio.h>
int a[100001],n;//定义一个全局变量,在函数中调用
void quicksort(int b,int c)
{
int i,j,t,x;
if(b>c)
return;
x=a[b];//这里的x是基准数
i=b;
j=c;
while(i!=j)
{
while(a[j]>=x&&i<j)//先从右往左找
j--;
while(a[i]<=x&&i<j)//再从左往右找
i++;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}//归位基准数
a[b]=a[i];
a[i]=x;
quicksort(b,i-1);//利用递归继续处理左边的数
quicksort(i+1,c);//利用递归继续处理右边的数
}
int main(void)
{
int i,j,t;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);//数据的赋值
}
quicksort(1,n);//快速排序的调用
for(i=1;i<=n;i++)
{
printf("%d ",a[i]);//输出排序后的结果
}
return 0;
}
下面说一下快速排序的时间复杂度,它最好可以达到O(nlog2n),最坏达到O(n2),平均在O(nlog2n)左右,空间复杂度:O(nlog2n)
所以说他是非常不稳定的,做题的时候一定要看数据范围选出适合的排序方法,才能保证不会时间超限。