“歸併”
將兩個或者兩個以上的有序序列合併成一個新的有序序列
歸併示例: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);
}
分析: