排序—归并排序

归并排序是一种高效的排序算法,具有最优时间复杂度O(nlogn)。它通过分解、求解和组合三个步骤实现排序。在空间复杂度上,归并排序需要额外的线性空间Θ(n)。尽管在主存排序中由于数据拷贝和额外内存需求导致应用受限,但通过巧妙的递归策略可以减少这些开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比较操作的次数介于(n log n)/2n log n - n + 1。 赋值操作的次数是(2nlogn)。最优时间复杂度O(n),最差时间复杂度O(nlogn),平均时间复杂度O(nlogn)。 归并算法的空间复杂度为:Θ (n)


设有数组A[low...high]

步骤:

1、分解: 和二分一样,取数组的中间点mid=(low+high)/2

2、求解: 分别对数组A[low..mid]和A[mid+1...high]进行归并排序

3、组合:将已排序的A[low..mid]和A[mid+1...high]组合成最终的有序组。


下面看一下图解:

下面给出具体的实现:

#include <iostream>
using namespace :: std;

template <class T>
class MergeSort
{
public:
	MergeSort(T * Arry, int n)
	{
		mArry = Arry;
		mArryLength = n;
	}
	MergeSort()
	{
	}
	//~MergeSort();
	MergeSort(const MergeSort &merge);
	MergeSort& operator=(const MergeSort &merge);

	void Mergesort();
	void Msort(T* TempArry, int left, int right);
	void Merge(T* TempArry, int Lpos, int Rpos, int RightEnd);
	void print();
private:
	T* mArry;
	int mArryLength;
};
template<class T>
MergeSort<T>::MergeSort(const MergeSort& merge)
{
	mArry = merge.mArry;
	mArryLength = merge.mArryLength;
}
template<class T>
MergeSort<T>& MergeSort<T>::operator=(const MergeSort &merge)
{
	mArry = merge.mArry;
	mArryLength = merge.mArryLength;
	return *this;
}
template<class T> 
void MergeSort<T>::Mergesort()
{
	T* TempArry;
	TempArry = new T[mArryLength];
	if (TempArry != NULL)
	{
		Msort(TempArry,0,mArryLength-1);
		delete TempArry;
	}
	else
	{
		cout<< "No space for tempArry";
	}
}
template<class T> 
void MergeSort<T>::Msort(T* TempArry, int left, int right)
{
	int Center;
	if (left < right)
	{
		Center = (left+right)/2;
		Msort(TempArry,left,Center);
		Msort(TempArry,Center+1,right);
		Merge(TempArry,left,Center+1,right);
	}
}
template<class T>
void MergeSort<T>::Merge(T* TempArry, int Lpos, int Rpos, int RightEnd)
{
	int i, LeftEnd, NumElements, TmpPos;
	LeftEnd =Rpos-1;
	TmpPos = Lpos;
	NumElements = RightEnd-Lpos+1;
	while (Lpos <= LeftEnd && Rpos <= RightEnd)
	{
		if (mArry[Lpos] <= mArry[Rpos])
		{
			TempArry[TmpPos++] = mArry[Lpos++];
		}
		else
		{
			TempArry[TmpPos++] = mArry[Rpos++];
		}
	}
	while (Lpos <= LeftEnd)
	{
		TempArry[TmpPos++] = mArry[Lpos++];
	}
	while (Rpos <= RightEnd)
	{
		TempArry[TmpPos++] = mArry[Rpos++];
	}
	for(i = 0; i < NumElements; i++,RightEnd--)
	{
		mArry[RightEnd] = TempArry[RightEnd];
	}
}
template<class T>
void MergeSort<T>::print()
{
	for (int i = 0; i < mArryLength; i++)
	{
		cout << mArry[i]<<" ";
	}
};
void main()
{
	int a[5] = {2,1,5,6,3};
	MergeSort<int> A(a,5);
	A.Mergesort();
	A.print();
}




归并排序很难用于主存排序,因为两个排序表需要线性附加内存,在整个算法中还需要数据在临时数组中来回拷贝的花销

这种拷贝可以通过在递归交替层次时谨慎转换A和TempArry得到避免

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值