描述
归并排序是典型的使用分治思想(divide-and-conquer)解决问题的案例。在排序的过程中,把原来的数组变成左右两个数组,然后分别进行排序,当左右的子数组排序完毕之后,再合并这两个子数组形成一个新的排序数组。整个过程递归进行,当只剩下一个元素或者没有元素的时候就直接返回。
leetcode示例
912.排序数组
给你一个整数数组 nums,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-an-array
C++代码实现
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
mergesort(nums,0,nums.size()-1);
return nums;
}
private:
void mergesort(vector<int>& nums,int left, int right){
if(left >= right) return;
int mid = left + (right - left)/2;
mergesort(nums,left, mid);
mergesort(nums,mid + 1, right);
vector<int> temp(right - left + 1,0);
int k = 0;
int i = left;
int j = mid + 1;
while(i <= mid && j <= right){
if(nums[i] < nums[j]){
temp[k++] = nums[i++];
}else{
temp[k++] = nums[j++];
}
}
while(i <= mid){
temp[k++] = nums[i++];
}
while(j <= right){
temp[k++] = nums[j++];
}
for(int i = 0; i < temp.size(); i++){
nums[left + i] = temp[i];
}
}
}
时间复杂度上归并排序能够稳定在O(nlogn)的水平,在每一级的合并排序数组过程中总的操作次数是n,总的层级数是logn,相乘得到最后的结果就是O(nlogn)。
空间复杂度是O(n),因为在合并的过程中需要使用临时数组来存放临时排序结果。
归并排序是稳定排序,保证原来相同的元素能够保持相对的位置。