八大排序算法之六--交换排序—快速排序(Quick Sort)
基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
快速排序的示例:
(a)一趟排序的过程:
(b)排序的全过程
算法的实现:
递归实现:
测试用的是杭电HDU 1040题 亲测AC啦
#include<iostream> using namespace std; const int N=1005; void print(int a[],int n)//输出数组元素 { cout<<a[0]; for(int k=1;k<n;k++) { cout<<" "<<a[k]; } } void swap(int &a,int &b)//使用引用 { int temp=a; a=b; b=temp; } int partition(int a[],int low,int high)//求分割点 { int key=a[low];//基准元素(第一个元素) while(low<high) {//先从右开始扫描 while(low < high &&a[high]>=key) --high; swap(a[low],a[high]); //在从左开始扫描 while(low < high &&a[low]<=key) ++low; swap(a[low],a[high]); } return low;//返回分割点 } void QuichSort(int a[],int low,int high) { if(low<high) { int pos=partition(a,low,high);//求得分割点 QuichSort(a,low,pos-1);//对低子表进行递归 QuichSort(a,pos+1,high);//对高子表进行递归 } } int main() { int s[N]; int T; cin>>T; while(T--) { int n; cin>>n; for(int j=0;j<n;j++) cin>>s[j]; QuichSort(s,0,n-1); print(s,n); cout<<endl; } return 0; }
整合版
void quick_sort(int s[], int l, int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--; if(i < j) s[i++] = s[j]; while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数 i++; if(i < j) s[j--] = s[i]; } s[i] = x; quick_sort(s, l, i - 1); // 递归调用 quick_sort(s, i + 1, r); } }
分析:
快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录。快速排序是一个不稳定的排序方法。
每天明白一点知识