• 高速排序算法C++实现


    //quick sort
    //STL中也有现成的高速排序算法。内部实现採用了下面技巧
    //1)枢轴的选择採取三数取中的方式
    //2)后半段採取循环的方式实现
    //3)高速排序与插入排序结合
    #include<vector>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    //这一版本号是最简单实现版本号。对于高速排序的优化主要有下面几个方面:
    //1)枢轴的选择。若枢轴选取不全适。比方,若每次递归时,两个子区间中的一个为空,则高速排序将退化为冒泡排序
    //关于枢轴的选择有多种:取最后一个元素、取第一个元素、三数取中、九数取中、随机值等
    //2)还有一方面是对迭代过程的优化。降低交换次数,降低递归深度等;
    template<class type>
    int partion1(vector<type>& vec,int start,int end)
    {//高速排序的核心部分
    	//取最后一个作为枢轴和第一个作为枢轴程序相似,下面是取最后一个元素作为枢轴
    	int key=vec[end];
    	int fast,slow;
    	fast=slow=start;
    
    	//用两个指针的移动实现
    	for(;fast<end;++fast)
    	{
    		if(vec[fast]<key)
    		{
    			if(fast!=slow)
    			{
    				int tmp=vec[slow];
    				vec[slow]=vec[fast];
    				vec[fast]=tmp;
    			}
    			slow++;
    		}
    	}
    	int tmp=vec[slow];
    	vec[slow]=vec[end];
    	vec[end]=tmp;
    	return slow;
    }
    
    //三数取中
    template<class type>
    int midNumber(type a,type b,type c)
    {
    	int big1=max(a,b);
    	int big2=max(a,c);
    	int big3=max(b,c);
    
    	return min(big1,min(big2,big3));
    }
    
    template<class type>
    int partion2(vector<type>& vec,int start,int end)
    {
    	//3数取中和9数取中的方式,保证了一定随机性,下面是3数取中的方式
    	int key=midNumber(vec[start],vec[(start+end)/2],vec[end]);
    
    	int midNumPos=0;
    	if(key==vec[start])
    		midNumPos=start;
    	else if(key==vec[end])
    		midNumPos=end;
    	else
    		midNumPos=(start+end)/2;
    
    	vec[midNumPos]=vec[end];
    	vec[end]=key;
    
    	//如今採用一种和上一种方案不同的交换方式
    	while(start<end)
    	{//枢轴的位置一直在改变
    		while(start<end && vec[start]<=key)
    			start++;
    
    		int tmp=vec[start];
    		vec[start]=vec[end];
    		vec[end]=tmp;
    
    		while(start<end && vec[end]>=key)
    			end--;
    
    		tmp=vec[start];
    		vec[start]=vec[end];
    		vec[end]=tmp;
    	}
    
    	return start;
    }
    
    template<class type>
    int partion3(vector<type>& vec,int start,int end)
    {//取随机数的方法
    	int keyNumPos=start+rand()%(end-start);
    	int tmp=vec[keyNumPos];
    	vec[keyNumPos]=vec[end];
    	vec[end]=tmp;
    
    	int key=vec[end];
    	while(start<end)
    	{//枢轴的位置一直在改变
    		while(start<end && vec[start]<=key)
    			start++;
    
    		tmp=vec[start];
    		vec[start]=vec[end];
    		vec[end]=tmp;
    
    		while(start<end && vec[end]>=key)
    			end--;
    
    		tmp=vec[start];
    		vec[start]=vec[end];
    		vec[end]=tmp;
    	}
    	return start;
    }
    //以上是三种对枢轴的优化方法。无非就是避免高速排序恶化
    //下面是避免不必要的交换过程
    template<class type>
    int partion4(vector<type>& vec,int start,int end)
    {//取随机数的方法
    	int keyNumPos=start+rand()%(end-start);
    	int tmp=vec[keyNumPos];
    	vec[keyNumPos]=vec[end];
    	vec[end]=tmp;
    
    	int key=vec[end];
    	while(start<end)
    	{//观察可知,交换的过程中,总有一个数是key,所以当须要赋key值时能够直接跳过,于是能够降低赋值操作
    		while(start<end && vec[start]<=key)
    			start++;
    
    		vec[end]=vec[start];//end以start覆盖
    
    		while(start<end && vec[end]>=key)
    			end--;
    
    		vec[start]=vec[end];//start以end覆盖
    	}
    	vec[start]=key;
    	return start;
    }
    
    
    template<class type>
    void qSort1(vector<type>& vec,int start,int end)
    {
    	if(start>=end)return;
    	int index=partion4(vec,start,end);//key
    	qSort1(vec,start,index-1);
    	qSort1(vec,index+1,end);
    }
    
    //递归过程须要出栈入栈,成本较高,并且可能栈溢出。假设可能的话最好以循环方式取代递归
    template<class type>
    void qSort2(vector<type>& vec,int start,int end)
    {
    	if(start>=end)return;
    	
    	int index;//key
    	while(start<end)
    	{//后半段的递归过程以循环取代。相当于减小了递归深度
    		index=partion4(vec,start,end);//key
    		qSort2(vec,start,index-1);
    		start=index+1;
    	}
    }
    
    
    //当处理的数据量比較小时,插入排序的成本可能比高速排序成本更低,所以考虑在数据量较小时採用插入排序
    
    /*template<class type>
    void qSort3(vector<type>& vec,int start,int end)
    {
    	if(start>=end)return;
    	
    	int index;//key
    	if(end-start>VALUE)
    	{	
    		while(start<end)
    		{//后半段的递归过程以循环取代,相当于减小了递归深度
    			index=partion4(vec,start,end);//key
    			qSort3(vec,start,index-1);
    			start=index+1;
    		}
    	}
    	else
    	{
    		insertSort(vec,start,end);
    	}
    }*/
    
    template<class type>
    void quickSort(vector<type>& vec)
    {
    	int length=vec.size();
    	qSort2(vec,0,length-1);
    }
    
    int main()
    {
    	int a[10]={1,5,9,0,6,3,2,7,8,4};
    	vector<int> vec(a,a+10);
    
    	quickSort(vec);
    
    	for(int i=0;i<vec.size();++i)
    		cout<<vec[i]<<"  ";
    	cout<<endl;
    	return 0;
    }


  • 相关阅读:
    Delphi字符串函数大全
    Jackson 工具类使用及配置指南
    Mybatis中javaType和jdbcType对应关系
    Mybatis SqlSessionTemplate 源码解析
    GridView 使用技巧【转】
    Spring JSR250注解
    表格文字不换行
    Sql 分页
    从GridView生成DataTable
    故障诊断:解惑IIS服务器无法添加映射之谜
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7011009.html
Copyright © 2020-2023  润新知