• 排序类


    /**************************************
     *作者: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;
    }
    

    写完了只是做了初步测试,不知道会不会有错,欢迎大家指正!
  • 相关阅读:
    某些电脑前面板没声音问题
    安装win10笔记
    linux 时区问题
    JS实现网页飘窗
    缓存promise技术不错哦
    wepy相关
    生成keystore
    2017年终巨献阿里、腾讯最新Java程序员面试题,准备好进BAT了吗
    细思极恐-你真的会写java吗
    年终盘点:Java今年的大事记都在这里!
  • 原文地址:https://www.cnblogs.com/arbboter/p/4225225.html
Copyright © 2020-2023  润新知