二路归并排序主要运用了“分治算法”,分治算法就是将一个大的问题划分为n个规模较小而结构相似的子问题。
这些子问题解决的方法都是类似的,解决掉这些小的问题之后,归并子问题的结果,就得到了“大”问题的解。
二路归并排序主旨是“分解”与“归并”
分解:
1.将一个数组分成两个数组,分别对两个数组进行排序。
2.循环第一步,直到划分出来的“小数组”只包含一个元素,只有一个元素的数组默认为已经排好序。
归并:
1.将两个有序的数组合并到一个大的数组中。
2.从最小的只包含一个元素的数组开始两两合并。此时,合并好的数组也是有序的。

图1. 归并排序过程 图2. 合并两个有序数组
举例说明:
1.图中原始数组为{2,4,7,5,8,1,3,6},数组中元素的个数为8个。首先将8个元素的数组二分,每次分解后,
数组中元素的数目为原数组的一半。直到分解为只含有一个元素的数组。
2.将小的数组按序合并,每次合并后数组的大小为上层数组的一倍。此时数组中的元素都是按序排列的。
3.在合并两个有序数组。如图2
下面的是自顶向下递归实现2路归并排序:
#include <iostream>
using namespace std;
void Merge(int * a, int low, int mid, int high)
{
int i = low, j = mid + 1, p = 0;//对应a数组的下标
int * r = new int[high - low + 1];//申请另一个对应大小的数组来存放排好序的数据
while (i <= mid && j <= high)
{
r[p++] = (a[i] <= a[j]) ? a[i++] : a[j++];
}
while (i <= mid)
r[p++] = a[i++];
while (j <= high)
r[p++] = a[j++];
for (p = 0, i = low; i <= high; p++, i++)
a[i] = r[p];//最后再把有序数据存进a数组中,使得a数组对应部分数据有序
delete[] r;
}
//自顶向下(递归实现)
void MSort(int *a, int low, int high)
{
if (low<high)
{
int mid = (low + high) / 2;
MSort(a, low, mid);
MSort(a, mid + 1, high);
Merge(a, low, mid, high);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = { 2,4,7,5,8,1,3,6 };
int n = sizeof(a) / sizeof(int);
MSort(a, 0, n - 1);
for (int i = 0; i<n; i++)
cout << a[i] << " ";
cout << endl;
system("PAUSE");
return 0;
}
参考资料:《算法导论》2.1章节