归并排序
约翰·冯·诺伊曼(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/