排序类

/**************************************
 *作者:IT05 HUST
 *mail:husterfisher@gmail.com
 *时间:2012-11
 *说明:本类实现了一些常见的排序方法,
 * 每个方法有类内部使用的成员函数排序法,
 *同时还有静态成员函数排序法,内部的注释
 *为内部版本,一般无参数
 **************************************/

#include "stdafx.h"


#include <iostream>
#include <time.h>
using namespace std;
#ifdef ITEM
#undef ITEM
#endif

#define ITEM int

class MySort
{
	public:
		MySort(const int &size = 10);//构造含有size铬的数组 
		virtual	~MySort();

		static void swap( ITEM &a, ITEM &b );//交换a和b的值 
		static void Rand(ITEM *a, const int &len);//乱序数组a 
		void Rand();//内部版本,乱序 
		static void print(const ITEM *a, const int &len);//打印数组a的内容 
		void print()const;//内部版本,打印类成员函数 
		static void GetCostTime();//获取排序花费时间 
		static void Reserve(ITEM *a, const int &len);//数组翻转
		void Reserve();//内部版本,数组翻转
		
		static void Bubble(ITEM *a, int len);//冒泡排序 
		void Bubble();//内部版本,冒泡排序 
		static void BubbleFlag(ITEM *a, int len);//标志-冒泡排序
		void BubbleFlag();//标志-冒泡排序
		
		static void Insert(ITEM *a, int len);//插入排序 
		void Insert();//内部版本-插入排序 
		static void InsertFindMove(ITEM *a, int len);//插入排序,搜索和移位合在一起 
		void InsertFindMove();//内部版本-插入排序 ,搜索和移位合在一起  
		static void InsertSwap(ITEM *a, int len);//插入排序,交换插入
		void InsertSwap();//内部版本,插入排序,交换插入

		static void Shell(ITEM *a, int len);//Shell排序
		void Shell();//内部版本,shell排序

		static void Select(ITEM *a, int len);//选择排序
		void Select();//内部版本,选择排序

		static void Merge(ITEM *a, int len);//归并排序
		void Merge();//内部版本,归并排序
		static void BinaryMerge(ITEM *a, int start, int end, ITEM *temp);//对数组a分为两组递归归并排序
		static void MergeArray(ITEM *a, int start, int mid, int end, ITEM *temp);//合并有序数组

		static void Quick(ITEM *a, int low, int high);//快速排序
		void Quick();//内部版本,快速排序
		static int Partition(ITEM *a, int low, int high);//将数组a分离成两类

	private:
		ITEM *data;
		int size;
		static clock_t cost;
		
};
//初始化类的静态成员变量
clock_t MySort::cost = 0;
//构造函数 
MySort::MySort(const int &size)//构造含有size个的数组 
{
	try
	{
		data = new ITEM[size];
		this->size = size;
		srand((unsigned int)time(NULL));
		for( int i=0; i<size; i++ ) data[i] = rand()%100;
	}
	catch(const bad_alloc &e)
	{
		cout << "内存分配失败:" << e.what() << endl ;
		return;
	}
	catch(const exception &e)
	{
		cout << "程序执行异常:" << e.what() << endl;
		return;
	}
}

//析构函数 
MySort::~MySort()
{
	//如果ITEM为基本类型,可以这样 析构 
	delete data;
	//若ITEM为对象,需要使用数组类型析构
	//delete []data; 
	data = NULL;
	size = 0;
}

//交换函数 
void MySort::swap( ITEM &a, ITEM &b )
{
	ITEM t = a;
	a = b;
	b = t;
}

//乱序 
void MySort::Rand(ITEM *a, const int &len)
{
	srand((unsigned int)time(NULL));
	for( int i=0; i<len/2; i++ )
	{
		swap(a[rand()%len], a[rand()%len]);
	} 
} 
//内部版本-乱序 
void MySort::Rand()
{
	MySort::Rand(data,size); 
}

//打印函数 
void MySort::print(const ITEM *a, const int &len)
{
	for( int i=0; i<len; i++ ) cout << a[i] << "  ";
	cout << endl;
}
//内部版本的打印函数 
void MySort::print()const
{
	for( int i=0; i<size; i++ ) cout << data[i] << "  ";
	cout << endl;
}

//打印上一次排序所花费的时间 
void MySort::GetCostTime()
{
	cout << "排序所花费时间是:" << cost << "毫秒" << endl;
} 

//数组翻转
void MySort::Reserve(ITEM *a, const int &len)
{
	for( int i=0; i<len/2; i++ ) swap( a[i], a[len-1-i] );
}
//内部版本,数组翻转
void MySort::Reserve()
{
	MySort::Reserve(data, size);
}


//冒泡排序
// 一般的冒泡排序 
void MySort::Bubble(ITEM *a, int len)
{
	cout << "冒泡排序:\n";
	cost = clock();
	len--;
	for( int i=0; i<len; i++ )
	{
		for( int j=0; j<len-i; j++ )
		{
			if( a[j] > a[j+1] ) swap( a[j], a[j+1] );
		}
	}
	cost = clock() - cost;
}
//内部版本,一般的冒泡排序 
void MySort::Bubble()
{
	MySort::Bubble(data,size);
}
//标志-冒泡排序 
void MySort::BubbleFlag(ITEM *a, int len)
{
	cout << "冒泡排序(标志):\n";
	cost = clock();
	bool flag = true; //标志排序是否还要继续,flag为真表示还没排好序 
	len--;
	for( int i=0; i<len && true == flag; i++ )
	{
		flag = false;
		for( int j=0; j<len-i; j++ )
		{
			if( a[j] > a[j+1] ) 
			{
				flag = true;
				swap( a[j], a[j+1] );
			}
		}
	}
	cost = clock() - cost;
}
//内部版本,标志-冒泡排序
void MySort::BubbleFlag()
{
	MySort::BubbleFlag(data,size);
} 

//插入排序 
void MySort::Insert(ITEM *a, int len)
{
	cout << "直接插入排序:\n";
	cost = clock();
	int t = a[0];
	for( int i=1; i<len; i++ )
	{
		t = a[i];
		int j;
		for( j=i-1; j>=0; j-- )//找到插入点j 
		{
			if( t >= a[j] ) break;
			//之前将本循环体外的后面部分放在此处的else部分
			//发现错了,经debug发现当插入点为0的时候是不会执行else部分的
			//所以排序出错 
		}
		//移位和插入 
		j++; 
		if( j != i )//不需要交换位置 
		{
			int k = i;
			while( k>j )//后部分后移一位 
			{
				a[k] = a[k-1];
				k--;
			}
			//此次的a[i]的插入点 
			a[j] = t; 
		}
		
	}
	cost = clock() - cost;
}
//内部版本-插入排序 
void MySort::Insert()
{
	MySort::Insert(data, size);
}

//插入排序,查找插入点的时候移位
void MySort::InsertFindMove(ITEM *a, int len)
{
	cout << "直接插入排序(移位):\n";
	cost = clock();
	int t = a[0];
	for( int i=1; i<len; i++ )
	{
		t = a[i];
		int j;
		for( j=i-1; j>=0; j-- )//边找插入点边移位 
		{
			if( t >= a[j] ) break;
			else//移位 
			{
				a[j+1] = a[j];
			}
		}
		a[j+1] = t;
	}
	cost = clock() - cost;
}
//内部版本-插入排序,查找插入点的时候移位
void MySort::InsertFindMove()
{
	MySort::InsertFindMove(data, size);
}
//插入排序,查找插入点的时候交换
void MySort::InsertSwap(ITEM *a, int len)
{
	cout << "直接插入排序(交换):\n";
	cost = clock();
	for( int i=1; i<len; i++ )
	{
		int j;
		for( j=i; j>0; j-- )//边找插入点边移位 
		{
			if( a[j]<a[j-1] ) swap(a[j], a[j-1]);
			else break;
		}
	}
	cost = clock() - cost;
}
//内部版本,插入排序 ,查找插入点的时候交换
void MySort::InsertSwap()
{
	MySort::InsertSwap(data, size);
}

//shell排序
void MySort::Shell(ITEM *a, int len)
{
	cout << "Shell排序:\n";
	cost = clock();
	int step = len/2;//定义步长
	while( step )
	{
		for( int i=0; i<step; i++ )//多少步
		{
			for( int j=i+step; j<len; j+=step )//按组插入排序,采用交换的方法
			{
				for( int k=j; k>i; k-=step )//交换插入排序
				{
					if( a[k]<a[k-step] ) swap(a[k], a[k-step]);
					else break;
				}
			}
		}
		step /= 2;
	}
	cost = clock() - cost;
}
//shell排序,内部版本
void MySort::Shell()
{
	MySort::Shell(data, size);
}

//选择排序
void MySort::Select(ITEM *a, int len)
{
	cout << "选择排序:\n";
	cost = clock();
	for( int i=0; i<len-1; i++ )//选择次数
	{
		for( int j=i+1; j<len; j++ )//选择i以后的最小的放到a[i]位置处
		{
			if( a[j] < a[i] ) swap(a[j], a[i]);
		}
	}
	cost = clock()-cost;
}
//内部版本,选择排序
void MySort::Select()
{
	MySort::Select(data, size);
}

//归并排序
void MySort::Merge(ITEM *a, int len)
{
	cout << "归并排序:\n";
	cost = clock();
	ITEM *temp;
	try
	{
		temp = new ITEM[len];
		BinaryMerge(a, 0, len-1, temp);//调用递归函数进行排序
		delete temp;
		temp = NULL;
	}
	catch(const bad_alloc &e)
	{
		cout << "内存分配失败:" << e.what() << endl;
	}
	catch(const exception &e)
	{
		cout << "程序运行异常:" << e.what() << endl;
	}
	cost = clock() - cost;
}
//内部版本,归并排序
void MySort::Merge()
{
	MySort::Merge(data, size);
}
//对数组a分为两组递归归并排序
void MySort::BinaryMerge(ITEM *a, int start, int end, ITEM *temp)
{
	if(start < end)
	{
		BinaryMerge(a, start, (start+end)/2, temp);//左半部分排序
		BinaryMerge(a, (start+end)/2+1, end, temp);//右半部分排序
		MergeArray(a, start, (start+end)/2, end, temp );//合并两个有序数组
	}
}
//合并两个有序数组
void MySort::MergeArray(ITEM *a, int start, int mid, int end, ITEM *temp)
{
	int m = start, n = mid+1;
	int i=start;//temp数组从start开始
	while(m<=mid && n<=end)
	{
		if(a[m] < a[n]) temp[i++] = a[m++];
		else temp[i++] = a[n++];
	}
	while(m <= mid)//复制前半部分剩余的
	{
		temp[i++] = a[m++];
	}
	while(n <= end)
	{
		temp[i++] = a[n++];
	}
	m = start;
	while(m < i )//复制temp内容到a内,完成排序
	{
		a[m] = temp[m];
		m++;
	}
}

//快速排序
void MySort::Quick(ITEM *a, int low, int high)
{
	int key;
	if(low < high)
	{
		key = Partition(a,low,high);//把数组分为两类
		Quick(a, low, key-1);//对key前面的快排
		Quick(a, key+1, high);//对key后面的快排
	}
}
//将数组a分为两类
int MySort::Partition(ITEM *a, int low, int high)
{
	ITEM key = a[low];
	while(low < high)
	{
		while(low<high && a[high]>=key) high--;
		a[low] = a[high];
		while(low<high && a[low]<=key ) low++;
		a[high] = a[low];
	}
	a[low] = key;
	return low;//返回分割点(轴点)的位置
}
void MySort::Quick()//内部版本,快速排序
{
	MySort::Quick(data, 0, size-1);
}
int _tmain(int argc, char *argv[])
{
	MySort test(10);
	
	//test.Bubble();
	//test.print();
	//MySort::GetCostTime();
	//
	//test.Rand();
	//test.print();
	//test.BubbleFlag();
	//test.print();
	//MySort::GetCostTime();
	//
	//test.Rand();
	//test.print();
	//test.Insert();
	//test.print();
	//MySort::GetCostTime();
	//
	//test.Rand();
	////test.print();
	//test.InsertFindMove();
	////test.print();
	//MySort::GetCostTime();

	//test.Insert();
	//test.print();
	//MySort::GetCostTime();

	//test.print();
	//test.InsertSwap();
	//test.print();
	//test.GetCostTime();

	//test.print();
	//test.Select();
	//test.print();
	//test.GetCostTime();

	//test.Rand();
	//test.print();
	//test.Shell();
	//test.print();
	//test.GetCostTime();


	//test.print();
	//test.Merge();
	//test.print(); 
	//MySort::GetCostTime();

	//test.print();
	//test.Quick();
	//test.print();
	
	system("pause");
	return 0;
}

写完了只是做了初步测试,不知道会不会有错,欢迎大家指正!
原文地址:https://www.cnblogs.com/arbboter/p/4225225.html