常用模板2:归并排序

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函数对整个数组进行排序。最后,我们遍历数组并打印排序后的结果,然后删除临时数组。

你可能感兴趣的:(算法,c++,leetcode,数据结构)