一、 歸併排序的基本思想
歸併排序是利用先遞歸進行分解,將一個規模爲 的問題分解成兩個規模爲 的問題,再不斷的繼續進行遞歸分解成最終規模爲的問題。然後再逐漸的從小規模結果進行合併,最終得到完整的結果。也即分而治之的思想。
其圖解如下:原圖地址
二、算法分析
歸併排序使用了空間換時間的方式,用一個輔助數組來存儲每次排序後的結果,然後再將其複製到原數組對應的位置上,會將原數組中對應位置上 的值覆蓋掉。
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;
}
運行結果如下:
四、複雜度分析
- 空間複雜度爲
- 時間複雜度爲
參考資料:
圖解排序算法(四)之歸併排序
排序算法總結之歸併排序