现在的位置: 首页 > 综合 > 正文

编程珠玑 column 11 sorting

2013年07月25日 ⁄ 综合 ⁄ 共 1886字 ⁄ 字号 评论关闭

快速排序算法的比较。

在排序一个所有元素均相同的数组的时候:


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);    

}  

抱歉!评论已关闭.