常用排序算法

#pragma once
#ifndef _ALGSORT_H_
#define _ALGSORT_H_
#define M 10                                                                                                       //M的取值范围为5~25最佳;
template <class T>
class AlgSort
{
public:
	void BubbleSort(T a[], const int n)                                                              //冒泡排序算法;
	{
		for(int i=1; i<n; ++i)
			for(int j=n-1; j>=i; --j)
				if(a[j-1]>a[j])
				{
					T temp=a[j-1]; a[j-1]=a[j]; a[j]=temp;
				}
	}
	void newBubbleSort(T a[], const int n)                                                       //冒泡的改进排序算法;
	{
		bool exchange;
		for(int i=1; i<n; ++i)
		{
			exchange=false;
			for(int j=n-1; j>=i; --j)
				if(a[j-1]>a[j])
				{
					T temp=a[j-1]; a[j-1]=a[j]; a[j]=temp;
					exchange=true;
				}
			if(exchange==false) return;
		}
	}
	void InsertSort(T a[], const int left, const int right)                                 //直接插入排序算法;
	{
		T temp; int i, j;
		for(i=left+1; i<=right; ++i)
			if(a[i]<a[i-1])
			{
				temp=a[i]; j=i-1;
				do
				{
					a[j+1]=a[j]; j--;
				} while(j>=left&&temp<a[j]);
				a[j+1]=temp;
			}
	}
	void BinaryInsertSort(T a[], const int left, const int right)                      //折半插入排序算法;
	{
		T temp; int i, low, high, middle, k;
		for(i=left+1; i<=right; ++i)
		{
			temp=a[i]; low=left; high=i-1;
			while(low<=high)
			{
				middle=(low+high)/2;
				if(temp<a[middle]) high=middle-1;
				else low=middle+1;
			}
			for(k=i-1; k>=low; --k) a[k+1]=a[k];
			a[low]=temp;
		}
	}
	void ShellSort(T a[], const int left, const int right)                                   //希尔排序算法;
	{
		int i, j, gap=right-left+1;
		T temp;
		do
		{
			gap=gap/3+1;
			for(i=left+gap; i<=right; ++i)
				if(a[i]<a[i-gap])
				{
					temp=a[i]; j=i-gap;
					do
					{
						a[j+gap]=a[j];
						j-=gap;
					} while(j>=left&&temp<a[j]);
					a[j+gap]=temp;
			}
		} while(gap>1);
	}
	void QuickSort(T a[], const int left, const int right)                                 //快速排序算法;
	{
		if(left<right)
		{
			int pivotpos=Partition(a, left, right);
			QuickSort(a, left, pivotpos-1);
			QuickSort(a, pivotpos+1, right);
		}
	}
	void newQISort(T a[], const int left, const int right)
	{
		newQuickSort(a, left, right);                                                               //先进行快速排序;
		InsertSort(a, left, right);                                                                      //对基本有序的序列进行插入排序;
	}
	void QuickSort3(T a[], const int left, const int right)                               //三路划分快速排序算法,处理元素序列中的重复值;
	{
		int i, j, k, p, q;
		T pivot=a[right];
		if(right<=left) return;
		i=left-1; j=right; p=left-1; q=right;
		while(1)
		{
			while(a[++i]<pivot) if(i==j) break;
			while(pivot<a[--j]) if(j==i) break;
			if(i>=j) break;
			T temp=a[i]; a[i]=a[j]; a[j]=temp;
			if(a[i]==pivot)
			{
				p++;
				T temp=a[p]; a[p]=a[i]; a[i]=temp;
			}
			if(pivot==a[j])
			{
				q--;
				T temp=a[q]; a[q]=a[j]; a[j]=temp;
			}
		}
		T temp=a[i]; a[i]=a[right]; a[right]=temp;
		j--; i++;
		for(k=right-1; k>=q; k--, i++)
		{
			T temp=a[k]; a[k]=a[i]; a[i]=temp;
		}
		for(k=left; k<=p; k++, j--)
		{
			T temp=a[k]; a[k]=a[j]; a[j]=temp;
		}
		QuickSort3(a, left, j);
		QuickSort3(a, i, right);
	}
	void SelectSort(T a[], const int left, const int right)                                //直接选择排序算法;
	{
		for(int i=left; i<right; i++)
		{
			int k=i;                                                                                                      //在a[i]到a[n-1]寻找最小排序码的元素;
			for(int j=i+1; j<=right; j++)
				if(a[j]<a[k]) k=j;
			if(k!=i)
			{
				T temp=a[i]; a[i]=a[k]; a[k]=temp;
			}
		}
	}
	void MergeSort(T a[], T aa[], const int left, const int right)                    //两路归并排序算法;
	{
		if(left>=right) return;
		int mid=(left+right)/2;                                                                               //从中间划分为两个子序列;
		mergeSort(a, aa, left, mid);
		mergeSort(a, aa, mid+1, right);
		merge(a, aa, left, mid, right);                                                                    //合并;
	}
	void newMergeSort(T a[], T aa[], const int left, const int right)            //改进的两路归并排序算法;
	{
		doSort(a, aa, left, right);
		InsertSort(a, left, right);
	}
private:
	int Partition(T a[], const int low, const int high)
	{
		int pivotpos=low;
		T pivot=a[low];
		for(int i=low+1; i<=high; ++i)
			if(a[i]<pivot)
			{
				pivotpos++;
				if(pivotpos!=i)
				{
					T temp=a[pivotpos]; a[pivotpos]=a[i]; a[i]=temp;
				}
			}
		a[low]=a[pivotpos]; a[pivotpos]=pivot;
		return pivotpos;
	}
private:
	void newQuickSort(T a[], const int left, const int right)                   //取中间元素的快速排序算法;
	{
		if(right-left<=M) return;
		int pivotpos=newPartition(a, left, right);
		newQuickSort(a, left, pivotpos-1);
		newQuickSort(a, pivotpos+1, right);
	}
	int newPartition(T a[], const int left, const int right)
	{
		int i=left, j=right-1;
		if(left<right)
		{
			T pivot=median3(a, left, right);
			for(; ;)
			{
				while(i<j&&a[i]<pivot) i++;
				while(i<j&&pivot<a[j]) j--;
				if(i<j)
				{
					T temp=a[i]; a[i]=a[j]; a[j]=temp;
					i++; j--;
				}
				else break;
			}
			if(a[i]>pivot)
			{
				a[right]=a[i]; a[i]=pivot;
			}
		}
		return i;
	}
	T& median3(T a[], const int left, const int right)                                 //三者取中算法;
	{
		int mid=(left+right)/2; int k=left;
		if(a[mid]<a[k]) k=mid;
		if(a[right]<a[k]) k=right;
		if(k!=left)
		{
			T temp=a[left]; a[left]=a[k]; a[k]=temp;                                             //最小者交换到left位置;
		}
		if(mid!=right&&a[mid]<a[right])
		{
			T temp=a[mid]; a[mid]=a[right]; a[right]=temp;                             //中间值交换到right位置;
		}
		return a[right];
	}
private:
	void merge(T a[], T aa[], const int left, const int mid, const int right)  //两路归并排序算法;
	{
		for(int k=left; k<=right; k++)
			aa[k]=a[k];
		int s1=left, s2=mid+1, t=left;
		while(s1<=mid&&s2<=right)
		{
			if(aa[s1]<=aa[s2]) a[t++]=aa[s1++];
			else a[t++]=aa[s2++];
		}
		while(s1<=mid) a[t++]=aa[s1++];
		while(s2<=right) a[t++]=aa[s2++];
	}
private:
	void doSort(T a[], T aa[], const int left, const int right)
	{
		if(left>=right) return;
		if(right-left+1<M) return;
		int mid=(left+right)/2;
		doSort(a, aa, left, mid);
		doSort(a, aa, mid+1, right);
		improvedMerge(a, aa, left, mid, right);
	}
	void improvedMerge(T a[], T aa[], const int left, const int mid, const int right)
	{
		int s1=left, s2=right, t=left, k;
		for(k=left; k<=mid; k++)
			aa[k]=a[k];
		for(k=mid+1; k<=right; k++)
			aa[right+mid+1-k]=a[k];
		while(t<=right)
		{
			if(aa[s1]<=aa[s2]) a[t++]=aa[s1++];
			else a[t++]=aa[s2--];
		}
	}
};
#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值