一.步骤
快速排序算法平均时间复杂度为O(nlogn),快速排序是一种不稳定的排序算法
1.确定分界点
在快速排序算法中,我们需要在数组a中找到一个分界点x,x可以随意取数组a里的任何值,通常情况下取数组a中除了边界(除非数组a长度只有2必须取边界作为x)的一个值作为x。(原因代码中解释)
2.调整区间
选取x后,我们需要将区间调整为两部分,左半边的数小于等于x,右半边的数严格大于x。这里我们有两种方法去实现:
(1)空间换时间
新定义两个数组b,c。在遍历a的过程中如果遇到比x大的数,那么填入数组c中,否则填入数组b中。这样一来数组c中的数一定大于x,数组b中的数一定小于等于x。再将数组b,c依次回填给数组a,这样就相当于用另外的空间减少了时间复杂度。
(2)指针
新定义两个指针i,j分别指向数组a的头和尾。在i小于j的前提下不断循环一下过程:
用循环1使得i++,在此过程中如果a[i]>=x,则停止循环1。接着运行循环2使得j--,在此过程中如果a[j]<=x,则停止循环2。最后把a[i]与a[j]的值互换。
代码如下:
while(i<j){
do i++; while(a[i]<x);
do j--; while(a[j]>x);
if(i<j){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
3.递归
将调整好的“左数组”与“右数组”进行相同操作,数组a被不断调整,当数组a的子数组在调整过程中,如果子数组的长度为1,意为已经将所有的子数组调整完毕,即可停止递归。
二.代码
#include <iostream>
using namespace std;
const int M=1e6+10;
int n,a[M];
void quick_sort(int a[],int l,int r){
if(l>=r) return;
int x=a[(l+r)/2],i=l-1,j=r+1;//如果x=a[l],那么代码第19行必须写成quick_sort(a,l,j);
while(i<j){ //不可以是quick_sort(a,l,i),否则会出现递归死循环。
do i++; while(a[i]<x); //同理,如果x=a[r],那么代码第19行必须写成quick_sort(a,l,i);
do j--; while(a[j]>x); //不可以是quick_sort(a,l,j),否则会出现递归死循环。
if(i<j){ //总结下来就是左不能写左,右不能写右。
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
quick_sort(a,l,j);
quick_sort(a,j+1,r);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
quick_sort(a,1,n);
for(int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}