C++实现常用排序算法(快速排序、冒泡排序、希尔排序、折半插入排序、直接插入排序)

25 篇文章 0 订阅

https://blog.csdn.net/mfcing/article/details/53582185 

#ifndef SORT_ALGORITHM_H_
#define SORT_ALGORITHM_H_
#include <assert.h>
#include <iostream>
using std::cout;
using std::endl;
template<class T,int len>
//T为排序序列元素类型,len为序列元素数目
class CSort
{
public:
	CSort(const T* arr);
	virtual~ CSort();
	//直接插入排序算法
	void InsertSort()const;
	//折半插入排序算法
	void BinaryInsertSort()const;
	//希尔排序算法
	void ShellSort(int dk[],const int& count)const;
	//冒泡排序算法
	void BubbleSort()const;
	//快速排序算法
	void QuickSort()const;
	//打印出数据
	void Show()const;
	//元素逆序输出
	void Scroll()const;
	//交换两个元素的值
	inline void Swap(T& t1,T& t2)const;
protected:
	//一趟希尔排序
	void ShellInsert(const int& dk)const;
	int Partition(int low,int high)const;
	void QSort(int low,int high)const;
private:
	T* buffer;//指向首地址,在整个过程中都不会改变之 
	int m_length;//元素数目
};
template<class T,int len>
CSort<T,len>::CSort(const T *arr):buffer(NULL),m_length(len)
{
	assert(arr&&len>0);
	buffer=const_cast<T*>(arr);
}
template<class T,int len>
CSort<T,len>::~CSort()
{
}
/*******************************************************************************************/
//直接插入排序
template<class T,int len>
void CSort<T,len>::InsertSort()const
{//arr 数组或指针首地址,len数组或指针中元素数目
	cout<<"开始进行直接插入排序----------------------------------------"<<endl;
	T* p=buffer;
	int i=1,j=0;
	for(;i<len;++i)
	{
		if(*(p+i)<*(p+i-1))
		{
			T temp=*(p+i);//暂存
			for(j=i-1;j>=0&&temp<*(p+j);--j)//循环知道找到插入位置
				*(p+j+1)=*(p+j);
			*(p+j+1)=temp;
		}
	}
}//时间复杂度为O(n^2)
/**********************************************************************************************/
//折半插入排序算法
template<class T,int len>
void CSort<T,len>::BinaryInsertSort()const
{
	cout<<"开始折半插入排序--------------------------------------------"<<endl;
	T* p=buffer;
	int i=0,j=0;
	for(i=1;i<len;++i)
	{
		T temp=*(p+i);
		int low=0,high=i-1;
		while(low<=high)
		{
			int mid=(low+high)/2;
			if(temp<*(p+mid))
				high=mid-1;
			else
				low=mid+1;
		}
		for(j=i-1;j>=high+1;--j)
			*(p+j+1)=*(p+j);
		*(p+high+1)=temp;
	}
}
/*********************************************************************************************************/
//希尔排序,对直接插入排序算法的一种改进
template<class T,int len>
void CSort<T,len>::ShellInsert(const int& dk)const
{//dk 希尔排序增量
	assert(dk>0);
	int i=0,j=0;
	T* p=buffer;
	for(i=dk;i<m_length;++i)
	{
		if(*(p+i)<*(p+i-dk))
		{
			T temp=*(p+i);
			for(j=i-dk;j>0&&temp<*(p+j);j-=dk)
				*(p+j+dk)=*(p+j);
			*(p+j+dk)=temp;
		}
	}
}
	/*(增量数组的最后一个元素值必须为1,因为最后一次是进行一次直接插入排序)
	给出几个常用增量数组:
	dk[k]=2^(t-k+1)-1时(t为排序趟数),时间复杂度为:O(n^1.5)
	dk[k]=2^(t-k)+1
	dk[k]=0.5(3^(t-k)-1)
	希尔排序的时间复杂度没有确定值,增量序列有多种取法*/
template<class T,int len>
void CSort<T,len>::ShellSort(int dk[],const int& count)const
{//dk[]为增量数组,count为增量数组的元素数目
	cout<<"开始进行希尔排序------------------------------------------"<<endl;
	for(int i=0;i<count;++i)
		ShellInsert(dk[i]);
}//时间复杂度为O(n^1.5)
/*************************************************************************************************/
//冒泡排序
template<class T,int len>
void CSort<T,len>::BubbleSort()const
{
	cout<<"开始进行冒泡排序------------------------------------------"<<endl;
	T* p=buffer;
	int i=0,j=0;
	for(;i<len;++i)
	{
		for(j=len-1;j>i;--j)
		{
			if(*(p+j)<*(p+j-1))
			{
				Swap(*(p+j),*(p+j-1));
				/*T temp=*(p+j);
				*(p+j)=*(p+j-1);
				*(p+j-1)=temp;*/
			}
		}
	}
}
/****************************************************************************************************/
//快速排序
template<class T,int len>
int CSort<T,len>::Partition(int low,int high)const//一趟快速排序
{
	T* p=buffer;
	T prikey=*(p+low);
	while(low<high)
	{
		while(low<high&&*(p+high)>=prikey)
			--high;
		*(p+low)=*(p+high);
		while(low<high&&*(p+low)<=prikey)
			++low;
		*(p+high)=*(p+low);
	}
	*(p+low)=prikey;
	return low;
}
template<class T,int len>
void CSort<T,len>::QSort(int low,int high)const
{
	if(low<high)
	{
		int ret=Partition(low,high);
		QSort(low,ret-1);
		QSort(ret+1,high);
	}
}
template<class T,int len>
void CSort<T,len>::QuickSort()const
{
	cout<<"开始快速排序--------------------------------------------------"<<endl;	
	QSort(0,m_length-1);
}
/**************************************************************************************************/
template<class T,int len>
void CSort<T,len>::Show()const// 显示数组中的元素
{
	cout<<"打印元素序列:"<<endl;
	T* p=buffer;
	for(int i=0;i<m_length;++i)
		cout<<*(p+i)<<"   ";
	cout<<endl;
}
template<class T,int len>
void CSort<T,len>::Scroll() const
{
	T* p=buffer;
	int low=0,high=m_length-1;
	while(low<high)
	{
		Swap(*(p+low),*(p+high));
		low++;
		high--;
	}
}
template<class T,int len>
inline void CSort<T,len>::Swap(T &t1, T &t2) const
{
	T temp=t1;
	t1=t2;
	t2=temp;
}
#endif;

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值