/**************************************
*作者: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;
}
写完了只是做了初步测试,不知道会不会有错,欢迎大家指正!