https://www.acwing.com/blog/content/277/
归并排序代码模板:
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else tmp[k ++ ] = q[j ++ ];
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
函数思路
归并排序是一种采用分治策略的排序算法。它将一个大问题(排序整个数组)分解为两个小问题(排序两个子数组),然后将这两个小问题的解(两个排序好的子数组)合并为大问题的解(整个排序好的数组)。
具体来说:
-
merge_sort函数接受一个整数数组q和两个索引l和r,表示要排序的数组的范围。它首先检查子数组的长度是否大于1,如果l >= r,则直接返回,因为长度为1或0的数组已经排序好了。
-
然后,函数找到子数组的中点mid,并递归地对左半部分(l到mid)和右半部分(mid+1到r)进行排序。
-
接下来,函数进行合并操作。它首先初始化一个新的数组tmp用于存储合并后的结果。然后,它使用两个指针i和j,分别指向两个已排序的子数组的开始。每次都选择i和j所指向的元素中较小的一个放入tmp,并将对应的指针向前移动一位。如果一个子数组中的所有元素都被选择完了,那么就将另一个子数组中剩下的元素全部复制到tmp。
-
最后,函数将tmp中的元素复制回原数组q。这样,原数组的l到r部分就被排序好了。
注意,这个函数还依赖于一个额外的数组tmp,它应该有足够的空间来保存q的l到r部分。这个数组应该在函数外部定义,例如在main函数中,或者作为全局变量。
使用样例
int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int* tmp = new int[n]; // 创建一个足够大的临时数组
merge_sort(arr, 0, n - 1, tmp);
for(int i = 0; i < n; i++)
cout << arr[i] << " ";
delete[] tmp; // 不要忘记删除临时数组
return 0;
}
在这个例子中,我们首先定义了一个整数数组arr,然后使用sizeof操作符计算数组的长度。然后,我们创建了一个临时数组tmp,并调用merge_sort函数对整个数组进行排序。最后,我们遍历数组并打印排序后的结果,然后删除临时数组。