归并排序

约翰·冯·诺伊曼(John von Neumann)在 1945 年提出了归并排序。归并排序基于分治思想将数组分段排序后合并,时间复杂度在最优、最坏与平均情况下均为 \(O(n \log n)\),空间复杂度为 \(O(n)\)

归并排序最核心的部分是合并(merge)过程:将两个有序的数组 a[i]b[j] 合并为一个有序数组 c[k]。再用分治法结合合并算法实现归并排序。

class Solution {
public:
    void mergeSort(vector<int>& nums) {
        if (nums.size() == 0) return;
        vector<int> result(nums.size(), 0);
        _mergeSortHelper(nums, 0, nums.size() - 1, result);
    }
    void _mergeSortHelper(vector<int>& nums, int start, int end, vector<int>& result) {
        if (start == end) return;
        int mid = (start + end) / 2;
        _mergeSortHelper(nums, 0, mid, result);
        _mergeSortHelper(nums, mid + 1, end, result);
        _merge(nums, start, end, result);
    }
    void _merge(vector<int>& nums, int start, int end, vector<int>& result) {
        int mid = (start + end) / 2;
        int start1 = start;
        int end1 = mid;
        int start2 = mid + 1;
        int end2 = end;
        int i = start1;
        int j = start2;
        int k = start;
        while (i <= end1 && j <= end2) {
            if (nums[i] <= nums[j]) {
                result[k] = nums[i];
                i++; k++;
            } else {
                result[k] = nums[j];
                j++; k++;
            }
        }
        while (i <= end1) {
            result[k] = nums[i];
            i++; k++;
        }
        while (j <= end2) {
            result[k] = nums[j];
            j++; k++;
        }
        for (int i = start; i <= end; i++) {
            nums[i] = result[i];
        }
    }
};
  • https://oi-wiki.org/basic/merge-sort/
  • https://leetcode.cn/leetbook/read/sort-algorithms/etdd3m/