目录
一、概念
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
其思想可用下图来表示:
从上图我们可以看到,归并的大体思路为:先保证小区间有序,再保证大区间有序。在思想上体现出了:分而治之的理念。
可总结为以下两点:
- 将待排序的线性表不断地切分成若干个子表,直到每个子表只包含一个元素,这时,可以认为只包含一个元素的子表是有序表。
- 将子表两两合并,每合并一次,就会产生一个新的且更长的有序表,重复这一步骤,直到最后只剩下一个子表,这个子表就是排好序的线性表。
二、递归版实现
对于用递归实现这个排序,我们可这样解决:
1. 开辟一个新数组,用于存放每次排完序的值。
2. 找到这个数组的最小单位,两两比较。
3. 每完成一组排序,便把新数组拷贝给原数组。
4. 重复以上操作,直到排序完成。
代码实现:
void _MergeSort(int* a, int* tmp, int left, int right)
{
if (left >= right)
{
return;
}
int mid = (left + right) / 2;
// 如果[begin, mid][mid+1, end]有序就可以进行归并了
_MergeSort(a, tmp, left, mid);
_MergeSort(a, tmp, mid + 1, right);
//归并
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int i = left;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
memcpy(a + left, t