归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
下面是归并排序的C++代码:
//把两个有序序列归并成一个有序序列
void Merge(int array[], int temparray[],int left, int middle, int right){
int index1=left;
int index2=middle;
int leftEnd = middle - 1;
int tmpPos = left;
//主循环
while (index1<=leftEnd&&index2<=right)
{
if (array[index1]<=array[index2])
{
temparray[tmpPos++] = array[index1++];
}
else{
temparray[tmpPos++] = array[index2++];
}
}
while (index1<=leftEnd) //复制第一部分剩下的
{
temparray[tmpPos++] = array[index1++];
}
while (index2<=right) //复制第二部分剩下的
{
temparray[tmpPos++] = array[index2++];
}
for (int i = left; i <= right;i++)
{
array[i] = temparray[i]; //最后面把值复制过去
}
}
//归并排序,迭代
void MSort(int array[], int tmpArray[],int left, int right){
int center;
if (left < right)
{
center = (left + right) / 2;
MSort(array, tmpArray,left, center);//左边有序
MSort(array, tmpArray,center + 1, right);//右边有序
Merge(array, tmpArray,left, center + 1, right);//将两个有序序列合并
}
}
//归并排序
bool MergeSort(int array[], int n){
int*tmpArray = new int[n];//新建一个临时数组
if (tmpArray==NULL)
{
return false;
}
MSort(array, tmpArray,0, n - 1);
delete[] tmpArray;
return true;
}
空间复杂度O(n)
稳定性:稳定
用途:速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列