比较操作的次数介于和
。 赋值操作的次数是
。最优时间复杂度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得到避免