一、 归并排序的基本思想
归并排序是利用先递归进行分解,将一个规模为
的问题分解成两个规模为
的问题,再不断的继续进行递归分解成最终规模为
的问题。然后再逐渐的从小规模结果进行合并,最终得到完整的结果。也即分而治之的思想。
其图解如下:原图地址
二、算法分析
归并排序使用了空间换时间的方式,用一个辅助数组来存储每次排序后的结果,然后再将其复制到原数组对应的位置上,会将原数组中对应位置上 的值覆盖掉。
1、如数组 [4,3,2,1] 的递归子问题为 [4,3] 和 [2,1] 其中先将 [4,3] 的排序结果放在辅助数组 temp 中(temp的大小为原数组 arr 的大小)。然后再将在 temp数组中排好序的结果复制到 arr 数组中的对应位置上,如下图所示。递归这个过程就是归并排序。
2、第一次递归后的排序结果如下
三、代码
#include<iostream>
#include<string>
using namespace std;
void Merge(int *arr, int *temp, int left, int mid,int right)
{
int i = left; //左边递归数组的指针
int j = mid + 1; //右边递归数组的指针
int index = 0;
while (i <= mid && j<=right)
{
if (arr[i] < arr[j])
{
temp[index++] = arr[i++];
}
else
{
temp[index++] = arr[j++];
}
}
while (i <= mid)
{
temp[index++] = arr[i++];
}
while (j <= right)
{
temp[index++] = arr[j++];
}
index = 0;
while (left <= right)
arr[left++] = temp[index++];
}
void MergeSort(int *arr, int *temp, int left,int right)
{
if (left < right)
{
int mid = left + (right - left) / 2;
MergeSort(arr, temp, left, mid); //左边归并排序,使得左子序列有序
MergeSort(arr, temp, mid + 1, right); //右边归并排序,使得右子序列有序
Merge(arr, temp, left, mid, right); //将两个有序子数组合并排序
}
}
int main()
{
int arr[] = { 4,3,2,1 };
int len = sizeof(arr) / sizeof(arr[0]);
//创建一个长度等于原数组长度的辅助数组,避免递归中频繁开辟空间
int *temp = new int[len];
MergeSort(arr,temp, 0, len-1);
delete[] temp;
for (int i = 0; i < len; ++i)
cout << arr[i] << " ";
cout << endl;
system("pause");
return 0;
}
运行结果如下:
四、复杂度分析
- 空间复杂度为
- 时间复杂度为
参考资料:
图解排序算法(四)之归并排序
排序算法总结之归并排序