https://leetcode-cn.com/problems/sort-an-array/
基于分治的思想,是一种稳定的排序算法,主要过程是将数组从中间分成两部分,然后将两个子数组继续分解,直到所有部分的元素个数都为1。然后从最底层开始将两个有序的子数组有序合并,通过递归,层层合并,最后得到一个有序的大数组。
- 时间复杂度 O(n*logn)
- n : 合并的时间复杂度
- logn:递归深度,合并次数
- 空间复杂度 O(n)
class Solution {public:vector<int> sortArray(vector<int>& nums) {mergeSort(nums, 0, nums.size() - 1);return nums;}// 将数组从中间分为两部分,然后将两个子数组继续分解,直到所有部分元素为1,使用递归从底开始层层合并。void mergeSort(vector<int> &nums, int l, int r) {if (l >= r) return;int mid = l + (r - l) / 2;mergeSort(nums, l, mid);mergeSort(nums, mid + 1, r);merge(nums, l, mid, r);}// 有序合并两个有序的子数列void merge(vector<int> &nums, int l, int mid, int r) {vector<int> tmp(r - l + 1);int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (nums[i] <= nums[j]) tmp[k++] = nums[i++];else tmp[k++] = nums[j++];}while (i <= mid) tmp[k++] = nums[i++];while (j <= r) tmp[k++] = nums[j++];for (int n : tmp) {nums[l++] = n;}}};
为什么内置算法用快排不用归并排序
虽然归并排序的时间复杂度比较稳定,但是归并排序不是原地排序算法,需要额外的空间,空间复杂度是O(n)。
虽然最坏情况下快排的时间复杂度是O(n2),但是它们的平均时间复杂度都是O(n*logn),而且还可以通过随机选择基准值来避免这种最坏的情况。
