它的基本框架就是:定左端一个数为基数x,提取出来(相当于空出一个位置放置右端比x大的数)。然后把小于x的数扔左边,大于x的数扔右边。
两个数i , j代表数组两端始末位置,开始扫描。因为第一步处理了左边,第二步就应该处理右边。
从右边扫描,大的不管,将比x小的数扔到数组左端,左端前进一位;再从左开始扫描,将比x大的扔到数组右端,右端后退一位。如此反复,当i = = j时,说明数组只剩下一个位置,这个位置上原本的数要么大于x要么等于要么小于。大于或小于的值会在i = = j之前被扔到右端或左端,等于的情况赋值也没影响。所以将x赋给这个位置。这样之后,数组[0( l ) ~i - 1] 全部小于x, [ i + 1~ r ] 全部大于x,完成一轮排序,分成两端再进行排序。
以此类推,最终当l = = r无法再进入下一层递归时,该区间必然有序(只有一个元素)。递减排序左右相反即可。
代码实现:(我这种以第一个为基准的代码会有一个弊端,如果一个序列本身有序,那么时间复杂度就会退化到O(n^2),推荐随机选取基准数或者选取中间的数)
#include <iostream>
#include <cmath>
using namespace std;
int a[100010];
void quicksort(int l,int r){
int i=l,j=r,x=a[l];
if (l<r){
while (i<j){
while (i<j&&a[j]>x)j--;
if (i<j)a[i++]=a[j];
while (i<j&&a[i]<x)i++;
if (i<j)a[j--]=a[i];
}
a[i]=x;
quicksort(l, i-1);
quicksort(i+1, r);
}
}
int main(){
int n;
cin>>n;
for (int i=1;i<=n;i++)cin>>a[i];
quicksort(1, n);
cout<<a[1];
for (int i=2;i<=n;i++)cout<<' '<<a[i];
cout<<endl;
return 0;
}