代码来自:https://www.geeksforgeeks.org/iterative-merge-sort/,对注释进行了翻译和扩充。
两个版本的归并排序,仅在mergeSort函数的实现上有区别。
非递归版本需要考虑当前mid、r的值是否超出了数组右边界,若超出则取值为n-1。有可能出现mid、r均为n-1的情况,此时调用merge,临时数组R[]的大小 n2 = r - mid = 0,是一个空数组,归并结果即为临时数组L[],关键代码:
for (int k=1; k<n; k = 2*k){
for (int l=0; l<n-1; l += 2*k){
int mid = min(l + k - 1, n-1);
int r = min(l + 2*k - 1, n-1);
merge(arr, l, mid, r);
}
}
两个版本的mergeSort函数均比较简单,其子函数merge完全一样,需要重点掌握其写法。
递归版本
递归版本是自顶向下的思路,如图所示:
#include<stdio.h>
void merge(int arr[], int l, int m, int r);
void mergeSort(int arr[], int l, int r) {
if (l < r){
int m = l+(r-l)/2; // 相当于 (l+r)/2,但能防止过大的l、h导致溢出
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}
/* 归并arr[l..m] 和 arr[m+1..r] */
void merge(int arr[], int l