分治归并排序算法实战
分治归并(Merge Sort)是分治思想在排序问题中的经典应用。其核心在于'拆分 - 排序 - 合并'三步走,将无序数组转化为有序数组。本质上,这是一个后序遍历的过程:不断向下细分数组,直到子问题足够小,然后从下往上把左右两分支的数组排序并合并。
1. 基础实现:排序数组
我们先从最基础的数组排序入手。归并排序的时间复杂度稳定在 O(n log n),空间复杂度为 O(n)。
关键细节
- 中点计算:
int mid = left + ((right - left) >> 1)等价于(left + right) / 2,但能避免整数溢出,且位运算效率略高。 - 合并逻辑:在合并阶段,
nums[left + j] = tmp[j]而不是nums[j] = tmp[j],这是因为递归过程中left不一定是 0,我们可能只对数组的一部分进行排序。 - 稳定性:归并排序是稳定排序,这对某些特定场景很重要。
C++ 代码实现
#include <iostream>
#include <vector>
using namespace std;
class Solution {
vector<int> tmp;
public:
vector<int> sortArray(vector<int>& nums) {
tmp.resize(nums.size());
mergeSort(nums, 0, nums.size() - 1);
return nums;
}
void mergeSort(vector<int>& nums, int left, int right) {
if (left >= right) {
return;
}
int mid = left + ((right - left) >> 1);
mergeSort(nums, left, mid);
(nums, mid + , right);
cur1 = left, cur2 = mid + , i = ;
(cur1 <= mid && cur2 <= right) {
tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];
}
(cur1 <= mid) {
tmp[i++] = nums[cur1++];
}
(cur2 <= right) {
tmp[i++] = nums[cur2++];
}
( j = ; j <= right - left; ++j) {
nums[left + j] = tmp[j];
}
}
};


