“归并”
将两个或者两个以上的有序序列合并成一个新的有序序列
归并示例:2-路归并排序
2-路归并的操作核心是:将数组中前后相邻的两个有序序列归并为一个有序序列
归并排序——“分而治之”
我们想要让整个序列有序,那么就要将它们先分割成小部分,分别管理,然后再合在一起,就能实现整个的有序了。这就像管理一个学校的学生,整体管理不好管理,就将学生分为一个班一个班,各个班管理好了,合并在一起,这个学校也就管理好了
// 合并两个已排好序的数组A[left...mid]和A[mid+1...right]
void Merge(int a[], int left, int mid, int right)
{
int len = right - left + 1;
int *temp = new int[len]; // 辅助空间O(n)
int index = 0;
int left1 = left; // 前一数组的起始元素
int left2 = mid + 1; // 后一数组的起始元素
//合并两个数组
while (left1 <= mid && left2 <= right)
{
//两个数组中较小的放入
temp[index++] = a[left1] <= a[left2] ? a[left1++] : a[left2++];
}
while (left1 <= mid)
{
temp[index++] = a[left1++];
}
while (left2 <= right)
{
temp[index++] = a[left2++];
}
//将合并好的序列拷贝回去
for (int i = 0; i < len; i++)
{
a[left++] = temp[i];
}
}
// 递归实现的归并排序(自顶向下)
void MergeSortR(int a[], int left, int right)
{
if (left == right) // 当待排序的序列长度为1时,递归开始回溯,进行merge合并操作
return;
int mid = (left + right) / 2;
MergeSortR(a, left, mid);
MergeSortR(a, mid + 1, right);
Merge(a, left, mid, right);
}
分析: