912.排序数组--归并排序

1.题目介绍

给你一个整数数组 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]

2.题解

2.1 归并排序(递归版本)

思路

归并排序利用了分治的思想来对序列进行排序。对一个长为 n 的待排序的序列,我们将其分解成两个长度为 n/2 的子序列。
每次先递归调用函数使两个子序列有序,然后我们再线性合并两个有序的子序列使整个序列有序。

代码

注意几个点:
1.递归终止条件 l>=r
2.找中点的时候是mid = (l+r)>>1 而不是(l+r)>>2
3.注意给这里的临时数组tmp重新扩容!!!使用resize即可
4.归并归并,就是将分治后两个有序数组融合为一个更大的有序数组

class Solution {
    vector<int> tmp;
    void mergeSort(vector<int> &nums, int l, int r){
        if(l >= r) return;
        int mid = (l + r) >> 1;
        // 递归调用
        mergeSort(nums, l, mid);
        mergeSort(nums, mid + 1, r);
        // 合并操作
        int cnt = 0;
        int left = l, right = mid + 1;
        while(left <= mid && right <= r){
            if (nums[left] <= nums[right]) tmp[cnt++] = nums[left++];
            else tmp[cnt++] = nums[right++];
        }
        while(left <= mid) tmp[cnt++] = nums[left++];
        while(right <= r) tmp[cnt++] = nums[right++];
        for(int i = 0; i < cnt; i++){
            nums[l+i] = tmp[i];
        }
    }
public:
    vector<int> sortArray(vector<int>& nums) {
        int n = nums.size();
        tmp.resize(n, 0);
        mergeSort(nums, 0, n-1);
        return nums;
    }
};

2.2 归并排序(迭代版本)

思路

这里直接自底向上进行迭代,注意控制好步长seg

代码

#include <algorithm>

template<typename T>
void merge_sort(T arr[], int len) {
    T* a = arr;
    T* b = new T[len];
    
    for (int seg = 1; seg < len; seg += seg) {
        for (int start = 0; start < len; start += seg + seg) {
            int low = start, mid = std::min(start + seg, len), high = std::min(start + seg + seg, len);
            int k = low;
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            
            // 合并两个有序区间
            while (start1 < end1 && start2 < end2)
                b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
            
            // 处理剩余数组部分
            while (start1 < end1)
                b[k++] = a[start1++];
            while (start2 < end2)
                b[k++] = a[start2++];
        }
        
        std::swap(a, b);
    }

    // 如果最终结果在临时数组 b 中,则复制回原数组
    if (a != &arr) {
        std::copy(a->begin(), a->end(), arr.begin());
    }   
    delete[] b;
}

int main() {
    int data[] = {34, 7, 23, 32, 5, 62};
    int len = sizeof(data) / sizeof(data[0]);
    
    merge_sort(data, len);
    
    for (int i = 0; i < len; i++) {
        std::cout << data[i] << " ";
    }
    
    return 0;
}

posted @ 2024-01-18 21:39  DawnTraveler  阅读(7)  评论(0编辑  收藏  举报