快速排序算法的比较。
在排序一个所有元素均相同的数组的时候:
qsort1每一次递归调用排序区间只能缩减1,只能排序好一个数字,可以从代码qsort1(m+1,u)中体现。因为所有元素相同时,qsort中m值执行的时候不会发生变化。qsort1排序区间的缩小只能体现在
qsort1(m+1,u)中。即要执行n-1次qsort1递归调用。每次qsort1递归调用,需进行<=n-1次比较,即上限为o(n)的次比较。
改进后快速排序在遇到相等元素的时候停止扫描,并且交换这些元素。
总结:swap执行总次数为n-1次,比较次数上限为o(n^2)。
qsort3:采用两个索引同时执行的方法。每一次递归调用,大约能使排序区间缩减一半,每一次i>j的时候停止当前的递归调用。总计o(lgn)次的递归调用。
每一次递归调用,需进行o(n)次比较,o(n)次交换,时间复杂度大约为O(nlogn)。注:这个时间复杂度只是针对所有元素相同的特殊情形
开始想着把do while的循环改成while循环。实际上是不是很方便。因为while(true)循环中i要先自増而不管循环条件是否成立
用了类似的代码
int i=l+1;
int j=u;
//i stop on element>=t
//j stop on element<=t
while(true){
while(i<=u&&x[i]<t)
i++
while(x[j]>t)
j--;
if(i>j)
break;
swap(x[i],x[j]);
}
结果导致某些情况下i==j,直接死循环了。而do while循环不会出现这种情况
#include<iostream>
#include<cstdlib>
using namespace std;
void swap(int &i,int &j){
int temp=i;
i=j;
j=temp;
}
void qsort3(int *x,int l,int u){
if(l>=u)return;
swap(x[l],x[l+rand()%(u-l)]);
int t=x[l];
int i=l;
int j=u+1;
//i stop on element>=t
//j stop on element<=t
while(true){
do{
i++;
}while(i<=u&&x[i]<t);
do{
j--;
}while(x[j]>t);
if(i>j)
break;
swap(x[i],x[j]);
}
swap(x[l],x[j]);
qsort3(x,l,j-1);
qsort3(x,j+1,u);
}
int main(){
int x[]={3,6,7,10,3,2,1};
qsort3(x,0,6);
for(int i=0;i<=6;i++)
cout<<x[i]<<endl;
return 0;
}
快速排序是一种分治的算法,快排的关键在于partition算法
下面这种快排算法来自Algorithms(By Robert Sedgewick,Kevin Wayne)
void qsort(int *x,int l,int u){
if(l>=u)return;
//swap(x[l],x[l+rand()%(u-l)]);
int t=x[l];
//i and j initialize to value beyond
//numbers to be sorted
int i=l;
int j=u+1;
//i stop on element>=t
//j stop on element<=t
while(true){
//i<u to ensure access
//within the valid range
while(x[++i]<t){
if(i>=u)
break;
}
while(x[--j]>t){}
if(i>=j)
break;
swap(x[i],x[j]);
}
swap(x[l],x[j]);
qsort(x,l,j-1);
qsort(x,j+1,u);
}
接下来的快排版本不保证正确性,暂时没有发现错误
void qsort3(int *x,int l,int u){
if(l>=u)
return;
//swap(x[l],x[l+rand()%(u-l)]);
int t=x[l];
int i=l+1;
int j=u;
//i stop on element>=t
//j stop on element<=t
while(true){
while(x[i]<=t){
if(i>=u)break;
i++;
}
while(x[j]>t){
j--;
}
if(i>=j)
break;
swap(x[i],x[j]);
}
swap(x[l],x[j]);
qsort3(x,l,j-1);
qsort3(x,j+1,u);
}