算法的思想:将大的问题化为小问题;问题性质不变
快速排序是在比较排序中相对较快,所以称为快速排序。对于一个数组a[n]快速排序中分界值需要取n次也就是说,每一个下标对应的值都需要取一次。
对于Partition()函数,最好的情况,每次划分所取的基准(也就是分界值)都恰为中值,即每次划分都产生两个大小为n/2的区域,此时,Partition的计算时间:T(n)=O(nlogn)。
源代码如下:
#include <iostream>
using namespace std;
template <class Type>
int Partition(Type a[],int p,int r)
{
int i=p,j=r+1;
Type x=a[p];//取分界的值x
while(true){//进入死循环
while((a[++i]<x)&&(i<r));//将小于分界值x的值放在x的左边
while(a[--j]>x);将大于分界值x的值放在x的右边
if(i>=j) break;//已经将左右区分开
swap(a[i], a[j]);//交换a[i]与a[j]的值,继续进入死循环
}
a[p]=a[j];//将分界值放在分界处
a[j]=x;
return j;//返回分界值
}
template <class Type>
void QS(Type a[],int p,int r)
{
if(p<r){
int q=Partition(a,p,r);//求的分界值
QS(a,p,q-1);//对左边排序
QS(a,q+1,r);//对右边排序
}
}
int main() {//测试快速排序
int *a;
int n;
cout<<"Please input the size of a"<<endl;
cin>>n;
a=new int[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
QS(a, 0, n-1);
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
下面是一个简单的示范:
a[] 5 4 739 8
下标 0 1 2 3 4 5
第一次时,取分界值x=5并且分别从左和从右开始比较,比较完之后i对应下标2,j对应下标3次时,因为i<j,所以,交换a[i],a[j]的值。即:
a[] 5 4 379 8
下标 0 1 2 3 4 5
继续比较。依次类推知道确定分界值x=5的下标,再对左半边进行排序,对右半边进行排序。
参考资料:高等学校规划教材 计算机算法设计与分析(第4版)◎王晓东编著