一,引言
归并排序作为七大排序中一种,本文将讲解其排序原理和代码实现。
二,逻辑讲解
来看一组动图:
首先先进行大逻辑的讲解,在一个乱序的数组中如图:

通过递归进行一次次分组如图:

分组逻辑:左右区间相加除以2,将一组分成两组,直到最后,每组只有一个数据分组结束。
因为单个数据看作为有序。
分组结束进行返回,如上图0有序,1有序,之后0和1进行排序,排完之后 0到1和2进行排序,排完之后0到2为有序,后面的逻辑都相同。如图:
这个排序的逻辑就逆着来,最小的区间有序,进而大一点的区间有序,进而更大一点区间有序,最后整个数组有序 。
下面我带入上述乱序数组进行排序。
第一步
首先如上图分成最小部分.0的位置为(5)单个看作有序,1的位置为(1)当个看作有序。将这两个返回。将0到1的位置进行排序,排序之后是(1)(5)
第二步
2的位置为(9)单个数据看作有序,进行返回,0到1的位置为有序---(1)(5),2的位置为有序---(9),将0到2进行排序。
第三步
进行排序0到4的右半边,和一二步逻辑相同。排序结束之后0到4为有序。
第四步
0到9的左半边有序,进行右半边的排序。逻辑和前三步相同,最后5到9有序。
第五步
进行0到9的排序。最终排序结束。
单趟排序逻辑:
分成最后单个有序返回之后进行[L----key]和[key+1-------R]的排序
通过创建一个新数组,将两组数据进行比较,然后依次拷贝到新数组 ,拷贝结束之后将新数组的数据拷贝回原数组。


第二步的单趟讲解:
和第一步的逻辑相同如图:

第三步的单趟排序:
第四步,第五步逻辑一致
这里就不依次画图了
三,代码实现:
cpp
void Merge(int* p, int* q, int left, int right)
{
if (left >= right)
{
return;
}
int begin1 = left;
int tag = left;
int keys = (left + right) / 2;
int end1 = keys;
int begin2 = keys + 1;
int end2 = right;
Merge(p, q, begin1, keys);
Merge(p, q, keys + 1, end2);
while (begin1 <= keys && begin2 <= end2)
{
if (p[begin1] < p[begin2])
{
q[tag] = p[begin1];
begin1++;
}
else
{
q[tag] = p[begin2];
begin2++;
}
tag++;
}
while (begin2 <= end2)
{
q[tag] = p[begin2];
begin2++;
tag++;
}
while (begin1 <= end1)
{
q[tag] = p[begin1];
begin1++;
tag++;
}
memcpy(p + left, q + left, (right - left+1) * sizeof(int));
}
p为原数组,q为拷贝数组,memcpy为拷贝函数,头文件在<string.h>中。
四,总结:
归并排序也是使用递归排序的一种,时间复杂度为O(Nlog^N)空间复杂度因为需要开辟新的空间所以为O(N),稳定性方面,在相同数据的相对数据并不会有所改变。所以该排序算法是稳定的。