1. 思路
首先,将数组划分成2个子数组,可以取左点,右点,中间点,随机点。然后用2个指针去扫,将扫到的特定数据交换,然后再递归左边的子数组,右边的子数组。
不需要用到额外的存储空间,速度又快,所以是很优秀的排序,平均时间能达到nlogn,最差情况下能达到n平方。算法导论里面是已右端点来做划分的,但是在已排序的情况下,会tle ,所以在oj里面,用随机的或者中间点,比较保险。
2. 代码
luogu 书里面的代码:
void quicksort(int a[],int l,int r){
int i = l,j =r ,flag = a[(l+r)/2];
do{
while (a[i]<flag)i++;
while (a[j]> flag)j--;
if (i<=j){
swap(a[i],a[j]);
i++,j--;
}
}while (i<=j);
if (l<j)quicksort(a,l,j);
if (i<r)quicksort(a,i,r);
}
acwing的代码:
void quick_sort(int q[], int l, int r)
{
//递归的终止情况
if(l >= r) return;
//第一步:分成子问题
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while(i < j)
{
do i++; while(q[i] < x);
do j--; while(q[j] > x);
if(i < j) swap(q[i], q[j]);
}
//第二步:递归处理子问题
quick_sort(q, l, j), quick_sort(q, j + 1, r);
//第三步:子问题合并.快排这一步不需要操作,但归并排序的核心在这一步骤
}
可以两个结合一下改成这样:
void quicksort(int a[],int l,int r){
if (l>=r)return ;
int i = l,j =r ,flag = a[(l+r)/2];
do{
while (a[i]<flag)i++;
while (a[j]>flag)j--;
if (i<=j){
swap(a[i],a[j]);
i++,j--;
}
}while (i<=j);
quicksort(a,l,j);
quicksort(a,i,r);
}