快速排序
快速排序由C. A. R. Hoare在1962年提出。
它的基本思想是:
通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序是一种交换类的排序,它同样是分治法的经典体现。
在一趟排序中将待排序的序列分割成两组,其中一部分记录的关键字均小于另一部分。然后分别对这两组继续进行排序,以使整个序列有序。在分割的过程中,枢纽值的选择至关重要,采取三位取中法,可以很大程度上避免分组"一边倒"的情况。
快速排序平均时间复杂度也为O(nlogn)级。
例子:
三数取中:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<cmath> 8 #define ll long long 9 #define DB double 10 #define inf 214748360000 11 #define mod 1000000007 12 using namespace std; 13 inline int read() 14 { 15 int x=0,w=1;char ch=getchar(); 16 while(!isdigit(ch)){if(ch=='-') w=-1;ch=getchar();} 17 while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); 18 return x*w; 19 } 20 int n,a[100003]; 21 void qsort(int l,int r) 22 { 23 int mid=a[(l+r)/2],i,j; 24 i=l;j=r; 25 do{ 26 while(a[i]<mid) i++; 27 while(a[j]>mid) j--; 28 if(i<=j) 29 { 30 swap(a[i],a[j]); 31 i++;j--; 32 } 33 }while(i<=j); 34 if(l<j) qsort(l,j); 35 if(i<r) qsort(i,r); 36 } 37 int main() 38 { 39 n=read(); 40 for(int i=1;i<=n;++i) a[i]=read(); 41 qsort(1,n); 42 for(int i=1;i<=n;++i) printf("%d ",a[i]); 43 return 0; 44 }
在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。