快速排序的多种实现比较

来源:互联网 发布:python 执行shell命令 编辑:程序博客网 时间:2024/09/21 08:16
快速排序是基于分治模式处理的:对一个典型子数组A[p...r]排序的分治过程为三个步骤:1.分解:A[p..r]被划分为俩个(可能空)的子数组A[p ..q-1]和A[q+1 ..r],使得A[p...q-1] <= A[q] <= A[q+1...r]2.解决:通过递归调用快速排序,对子数组A[p ..q-1]和A[q+1 ..r]排序。3.合并。
其中分解的方法有多种,很容易引起混淆,下面逐一介绍。
1. Lomuto从左至右单向扫描版:参见编程珠玑
int partition1(int A[], int p, int r){t = A[p];// 首元素为枢纽int m = p;for(i = p+1; i<=r; i++)        {     /*   invariant: A[p+1...m] < A[p] && A[m+1...i-1]>=A[p]  */if( A[i] < t)swap(A[++m], i)         }        swap(A[p],A[m]);      //这次交换不可少return m;              }
2. Lomuto从右至左单向扫描版:参见编程珠玑
int partition2(int A[], int p, int r){t = A[p]; // 首元素为枢纽int m = r+1;for(i = r; i>=p; i--)        {     /*   invariant: A[m...r] >= A[p] && A[m-1...i]<A[p]  */if( A[i] >= t)swap(A[--m], i)         }        // swap(A[p],A[m]); //这次交换已经包含在for循环内return m;              }
3. Lomuto从左至右单向扫描版:参见算法导论
int partition3(int A[], int p, int r){t = A[r]; // 尾元素为枢纽int m = p-1;for(i = p; i<r; i++)        {     if( A[i] <= t)swap(A[++m], i)         }        swap(A[r],A[m+1]); //这次交换不可少return m+1;              }

上述三个算法的缺点是:当A数组所有元素相同时,n-1次划分中每次

划分都需要O(n)时间去掉一个元素,时间复杂度O(n*n)。

4. Hoare双向扫描版:参见博客<结构之法>

int partition4(int A[],int p,int r)  //双向扫描  {    int key=A[p];  // 首元素为枢纽  int i=p-1;    int j=r+1;    for(;;)    {       do{            j--;        }while(A[j]>key);         do{           i++;        }while(A[i]<key);         if(i<j)       {           swap(A[i],A[j]);       }       else       {           return j;  //注意这里的返回值是j。      }     }  }  

5. Hoare变种:参见严蔚敏数据结构
int partition5(int A[],int p,int r)  //双向扫描。{ int key=A[p];   //以第一个元素为主元 int i=p; int j=r; while(i<j) {  while(key<=A[h] && i<j)    j--;  A[i]=A[j];  while(A[i]<=key && i<j)    i++;  A[j]=A[i]; } A[i]=key;   return i;    //注意这里返回的是i} 

6. STL qsort 算法:参见侯捷STL源码剖析

int partition6(int A[],int p,int r,int key) //双向扫描。{ //这里的key可以是数组中任意一元素的值,但通常是首、尾、中间元素的中位数的值。 //这里的r其实是数组最后元素的下一个元素,符合STL左闭右开的假定 while(true) {  while(A[p]<key)   ++p;  --r;  while(key<A[r])   --r;        if( !(p<r) )  return p; //注意这里返回的是pswap(A[p],A[r]);++r; }   } 
其实我感觉小于号改成小于等于号也行,可能是STL出于泛化的考虑,数据有可能不支持小于等于号。
以上是在看书和看博客过程中的一些思考,可能有些错误,仅记下来待以后看。

0 0
原创粉丝点击