归并排序:分治思想的经典应用
基本思想
归并排序(Merge Sort)是分治法(Divide and Conquer)的经典应用,由计算机科学先驱约翰·冯·诺依曼于 1945 年提出。其核心逻辑非常直观:将大问题分解为小问题,解决小问题后合并结果。
算法流程主要包含两个阶段:
- 分(Divide):递归地将当前数组分割成两个子数组,直到每个子数组只包含一个元素(单个元素天然有序)。
- 治(Conquer):将两个有序的子数组合并成一个新的有序数组。
归并排序的核心操作是合并两个有序数组。具体做法是每次比较两个数组的首元素,将较小者放入新数组,直到所有元素合并完成。
注意:在递归拆分时,区间的划分方式至关重要。通常采用
[begin, mid]和[mid+1, end]的划分方式,而非[begin, mid-1]和[mid, end],后者容易导致边界计算错误。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// 归并辅助函数:合并 [begin, mid] 和 [mid+1, end]
void _MergeSort(int* a, int* tmp, int begin, int end) {
// 递归终止条件:当子数组只有一个元素时
if (begin >= end) {
return;
}
// 计算中间点
int mid = (begin + end) / 2;
// 递归处理左右区间
_MergeSort(a, tmp, begin, mid);
_MergeSort(a, tmp, mid + 1, end);
// 开始归并
int begin1 = begin, end1 = mid;
int begin2 = mid + 1, end2 = end;
int i = begin;
// 双指针遍历,将较小的元素放入临时数组
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] < a[begin2]) {
tmp[i++] = a[begin1++];
} else {
tmp[i++] = a[begin2++];
}
}
(begin1 <= end1) {
tmp[i++] = a[begin1++];
}
(begin2 <= end2) {
tmp[i++] = a[begin2++];
}
(a + begin, tmp + begin, (end - begin + ) * ());
}
{
* tmp = (*)(() * n);
(tmp == ) {
perror();
;
}
_MergeSort(a, tmp, , n - );
(tmp);
tmp = ;
}
{
a[] = {, , , , , };
MergeSort(a, );
( i = ; i < (a) / (a[]); i++) {
(, a[i]);
}
;
}


