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