各种 快速排序 的比较~(仅仅是目前手上的资料出现的快速排序)

最近在复习算法,下面是我自己整理的程序

普通情况下的最快的排序算法——快速排序

下面直接贴代码~


#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
/**
因为测试排序的数据有1,000,000条,且使用数组0号位作为两数交换时的temp空间,再加上文件末尾空行,所以数组空间为1000002
**/
static const int ArraySize = 1000002;

/**
交换两个数,使用数组0号位
**/
template <typename Item>
void exch(Item a[],const int x,const int y)
{
	a[0]=a[x];
	a[x]=a[y];
	a[y]=a[0];
}

/**
把小的值放在前面
**/
template <typename Item>
void compexch(Item a[],const int x,const int y)
{
	if ( a[x] > a[y] ) exch( a,x,y );
}

/**
算法I-IV(C++实现)中的插入排序,因为在后面的优化的排序算法中需要使用到,因此也贴出来
**/
template <typename Item>
void insertion(Item a[],const int l,const int r)
{
	for (int i = r; i > l; --i)//把最小的值放在最左边 
		compexch(a,i-1,i);
	for (int i = l+2; i <= r; ++i)//从第三个开始遍历数组,并插入到前面已排好序的序列中(保持排序)
	{
		int j=i;
		Item v=a[i];
		while(v<a[j-1])//比待插入的数大的数往后移动
		{
			a[j] = a[j-1];
			--j;
		}
		a[j] = v;
	}
}

/**
数据结构 严蔚敏版的划分函数:
**/
template <typename Item>
int partition_v1(Item a[],const int l,const int r)
{
	Item temp = a[l];
	int i = l,j=r;
	while( i < j )
	{
		while(i < j && a[j] >= temp) --j;
		if(a[j]<temp){
			a[i] = a[j];
			++i;
		}
		while(i < j && a[i] <= temp) ++i;
		if(a[i]>temp){
			a[j] = a[i];
			--j;
		}
	}
	a[i] = temp;
	return i;
}

/**
数据结构 严蔚敏版的快速排序(1,000,000条数据使用0.25s)
**/
template <typename Item>
void quicksort1(Item a[],const int l,const int r)
{
	if(l<r){
		int i = partition_v1(a,l,r);
		quicksort1(a, l, i-1);
		quicksort1(a, i+1, r);
	}
}

template <typename Item>
void quicksort1_1(Item a[],const int l,const int r)
{
	if(r-l>M){
		int i = partition_v1(a,l,r);
		quicksort1(a, l, i-1);
		quicksort1(a, i+1, r);
	}
	else
	{
		insertion(a,l,r);
		return ;
	}
}

template <typename Item>
void quicksort1_2(Item a[],const int l,const int r)
{
	if(r-l>M){
		exch(a, (r+l)/2, r-1);
		compexch(a, l, r);
		compexch(a, l, r-1);
		compexch(a, r-1, r);

		int i = partition_v1(a,l+1,r-1);
		quicksort1(a, l, i-1);
		quicksort1(a, i+1, r);
	}
	else
	{
		insertion(a,l,r);
		return ;
	}
}

/**
算法I-IV(C++实现) 的划分函数:
**/
template <typename Item>
int partition_v2(Item a[],const int l,const int r)
{
	int i = l-1,j=r;
	Item v= a[r];
	while (1)
	{
		while (a[++i] < v) ;
		while (v < a[--j]) if (j == i) break;
		if (i>=j) break;
		exch(a,i,j);
	}
	exch(a,i,r);
	return i;
}

/**
算法I-IV(C++实现) 的快速排序:原始版本(1,000,000条数据平均使用0.374s)
**/
template <typename Item>
void quicksort2(Item a[],const int l,const int r)
{
	if (r <= l) return;
	int i = partition_v2(a,l,r) ;
	quicksort2(a,l,i-1);
	quicksort2(a,i+1,r);
}


/**
算法I-IV(C++实现) 的快速排序:使用插入排序改进版(1,000,000条数据平均使用0.39s)
**/
static const int M=10;

template <typename Item>
void quicksort2_1(Item a[],const int l,const int r)
{
	if( r-l <= M){ 
		insertion(a,l,r);
		return ;
	}
	int i = partition_v2(a,l,r) ;
	quicksort2_1(a,l,i-1);
	quicksort2_1(a,i+1,r);
}

/**
算法I-IV(C++实现) 的快速排序:三个数的中值+先快速排序再插入排序改进版(1,000,000条数据平均使用0.31s)
**/
template <typename Item>
void quicksort2_2(Item a[],const int l,const int r)
{
	if( r-l <= M) return ;
	//取最左、最右、以及中间三个值中的中值作为划分元素
	exch(a, (l+r)/2, r-1);
	compexch(a, l, r-1);
	compexch(a, l, r);
	compexch(a, r-1, r);

	int i = partition_v2(a,l+1,r-1) ;
	quicksort2_2(a,l,i-1);
	quicksort2_2(a,i+1,r);
}
template <typename Item>
void hybirdsort(Item a[],const int l,const int r)
{
	quicksort2_2(a,l,r);
	insertion(a,l,r);
}

/**
算法I-IV(C++实现) 的快速排序:三路划分(1,000,000条数据平均使用0.36s)
**/
template <typename Item>
int operator==(const Item &A,const Item &B)
{
	return !less(A,B) && !less(B,A);
}
template <typename Item>
void quicksort2_3(Item a[],const int l,const int r)
{
	int k;Item v=a[r];
	if (r<=l) return;
	int i = l-1,j=r,p=l-1,q=r;
	while (1)
	{
		while (a[++i]<v) ;
		while (v<a[--j]) if (j==l) break;
		if (i>=j) break;
		exch(a,i,j);
		if(a[i] == v ){p++;exch(a,p,i);}
		if(a[j] == v ){p++;exch(a,q,j);}
	}
	exch(a,i,r);j=i-1;i=i+1;
	for (k=l ; k<=p; ++k,--j) exch(a,k,l);
	for (k=r-1; k>=q; --k,++i) exch(a,k,i);
	quicksort2_3(a,l,j);
	quicksort2_3(a,i,r);
}

/**
算法导论 的划分函数
**/
template<typename Item>
int partition_v3(Item a[],const int l,const int r)
{
	Item x = a[r];
	int i = l-1;
	for (int j = l; j<r ;++j)
	{
		if (a[j]<x) 
		{
			++i;
			exch(a,i,j);
		}
	}
	exch(a,i+1,r);
	return i+1;
}

/**
算法导论 的划分函数随机化版本:随机选区划分元素
**/
template<typename Item>
int partition_v3_rand(Item a[],const int l,const int r)
{
	srand((unsigned)time(NULL));
	int i = 1 + (rand()*100)%(r-l);
	exch(a,r,l+i);
	return partition_v3(a,l,r);
}

/**
算法导论 的快速排序(1,000,000条数据平均使用0.65s)
**/
template<typename Item>
void quicksort3(Item a[],const int l,const int r)
{
	if (l<r)
	{
		int i = partition_v3(a,l,r);
		quicksort3(a,l,i-1);
		quicksort3(a,i+1,r);
	}
}
/**
算法导论 的快速排序 :随机化版本(1,000,000条数据平均使用0.75s)
**/
template<typename Item>
void quicksort3_rand(Item a[],const int l,const int r)
{
	if (l<r)
	{
		int i = partition_v3_rand(a,l,r);
		quicksort3_rand(a,l,i-1);
		quicksort3_rand(a,i+1,r);
	}
}

/**
读文件 inFile , 会把data数组中的内容全部清空,并重新分配空间
**/
template <typename Item>
bool readData(const char* inFileName , Item *data)
{
	ifstream inFile(inFileName);
	if (inFile.fail())
	{
		cout<<"文件操作失败!"<<endl;
		inFile.close();
		return false;
	}

	for (int i=1;i!=ArraySize-1;++i)
	{
		inFile>>data[i];
	}
	inFile.close();
	if (data == NULL)
	{
		return false;
	}
	return true;
}

/**
写文件 outFile
**/
template <typename Item>
bool writeData(const char* outFileName, Item data[])
{
	ofstream outFile(outFileName);//打开并清空文件
	if( outFile.fail())
	{
		cout<<"文件操作失败!"<<endl;
		outFile.close();
		return false;
	}
	for (int i=1; i!=ArraySize; ++i)
	{
		outFile<<data[i]<<endl;
	}
	outFile.flush();
	outFile.close();
	return true;

}
/**
数组拷贝
**/
template <typename Item>
void arrayClone(Item sourceArray[],Item targetArray[])
{
	for (int i=0; i != ArraySize; ++i)
	{
		targetArray[i] = sourceArray[i];
	}
}

/**
调用排序(只调用writeData,因此在使用此函数前必须先把文件数据读入数组data中)
**/
template <typename Item>
void mySort(Item data[],void (*pFunc)(Item a[],const int l,const int r))
{
	clock_t start_time,end_time;
	double totaltime;
	start_time = clock();//计时开始

	pFunc(data,1,ArraySize-2);

	end_time = clock();//计时结束
	//totaltime=(double)(end_time-start_time)/CLOCKS_PER_SEC;
	//cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;
	totaltime=(double)(end_time-start_time);
	cout<<"\n此程序的运行时间为"<<totaltime<<"ms!"<<endl;
}

/**
调用排序算法进行排序
**/
template <typename Item>
bool mySort(const char* inFileName,
			const char* outFileName,
			void (*pFunc)(Item a[],const int l,const int r))
{
	ifstream inFile(inFileName);//打开输入文件
	ofstream outFile(outFileName);//打开并清空文件
	if(inFile.fail() || outFile.fail())
	{
		cout<<"文件读取失败!"<<endl;
		outFile.close();
		inFile.close();
		return false;
	}
	Item *a = new Item[ArraySize];
	for (int i=1;i!=ArraySize-1;++i)
	{
		inFile>>a[i];
	}

	clock_t start_time,end_time;
	double totaltime;
	start_time = clock();//计时开始

	pFunc(a,1,ArraySize-2);

	end_time = clock();//计时结束
	totaltime=(double)(end_time-start_time)/CLOCKS_PER_SEC;
	cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;

	for (int i=1;i!=ArraySize-1;++i)
	{
		outFile<<a[i]<<endl;
	}
	delete []a;
	inFile.close();
	outFile.flush();
	outFile.close();
	return true;
}
下面是测试结果:




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值