1.快排
1.快排
方法
1.确定分界点(可以是p[0],p[n],p[n/2],随机)
2.(重点)调整区间(将<=n的放到左侧,把>=n的放到右侧)分成两部分
用两个指针分别指两端,先后向中间靠拢

3.递归处理左右两边。
(不稳定)
可以想办法让每个数不一样:比如把里面的元素变成二元组a=><a,i>。
代码
1.暴力
//用空间换时间,多开两个数组 int a[n]; int b[n]; int p[2*n];//排p序 int n1=0,n2=0; for (int i=0;i<=2*n;i++) { if(p[i]>=p[0]) { a[n1++]=p[i]; }else if(p[i]<p[0]) { b[n2++]=p[i]; } }
2.优美而简洁 q[]
#include<iostream> using namespace std; const int N =1e6+10; int n; int q[N]; void quick_sort(int q[],int l,int r) { if(l>=r) return ;//如果数组里只有1个或没有数,直接结束 //1.int q[r] //2.int q[(l+r+1)/2] (有时候用两边会超时) int x=q[l],i=l-1,j=r+1;//因为是先同时向中间靠拢,先把两个指针放在数组外面 // while(i<j)//i不能大于j否则结束 { do i++;while(q[i]<x);//向中间走直到遇到大于x的 do j--;while(q[j]>x);//向中间走直到遇到小于x的 if(i<j) swap(q[i],q[j]);//将两个数交换位置,再继续走 } //quick_sort(q,l,i-1) //quick_sort(q,i,r) quick_sort(q,l,j);//递归 quick_sort(q,j+1,r); /*eg: 2 1 2 用i则不能取到左边界,把x取值改成向上取整 用j则不能取到右边界,把x取值改成向下取整 取到边界会导致递归死循环 *************************** 以j为划分时,x不能选q[r] (若以i为划分,则x不能选q[l]) 假设 x = q[r] 关键句子quick_sort(q, l, j), quick_sort(q, j + 1, r); 由于j的最小值是l,所以q[j+1..r]不会造成无限划分 但q[l..j](即quick_sort(q, l, j))却可能造成无限划分,因为j可能为r 举例来说,若x选为q[r],数组中q[l..r-1] < x, 那么这一轮循环结束时i = r, j = 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; } 注意:由于使用do-while循环,所以i和j一定会!!!自增!!!,使得循环会继续下去,但是如果采用while循环(i和j的初始化做出对应的变更),i和j在特殊情况下不自增的话,循环就会卡死 例如: while(q[i] < x) i++; while(q[j] > x) j--; 当q[i]和q[j]都为 x 时, i 和 j 都不会更新,导致 while 陷入死循环
浙公网安备 33010602011771号