【归并排序模板】

系列文章目录

提示: 以下是其他排序算法的链接🔗

十大排序算法模板,点击跳转

文章目录

  • 系列文章目录
  • 什么是归并排序?

什么是归并排序?

归并排序(Merge Sort)是一种基于分治思想的排序算法,它将待排序序列分成两个子序列,分别对子序列进行排序,然后将两个有序的子序列合并成一个有序的序列。

归并排序的步骤如下:

  1. 将待排序序列分成两个子序列,直到每个子序列只有一个元素。
  2. 对每个子序列进行排序,可以使用递归调用归并排序。
  3. 将两个有序的子序列合并成一个有序的序列,得到最终的排序结果。

归并排序的时间复杂度为O(nlogn),其中n是待排序序列的长度。归并排序是一种稳定的排序算法,它的空间复杂度为O(n),需要额外的空间来存储临时的子序列。


代码模板(示例):

力扣912排序数组练习

递归版

class Solution {
    // 全局变量节省空间
    public static int[] tmp = null;

    public int[] sortArray(int[] nums) {
        //归并排序(递归)
        tmp = new int[nums.length];
        mergeSort(nums, 0, nums.length - 1);
        return nums;
    }

    public void mergeSort(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);
        //合并左右
        int cur1 = left, cur2 = mid + 1, i = 0;
        while (cur1 <= mid && cur2 <= right)
            tmp[i++] = nums[cur1] > nums[cur2] ? nums[cur2++] : nums[cur1++];
        //处理未拷贝的数
        while (cur1 <= mid) 
            tmp[i++] = nums[cur1++];
        while (cur2 <= right) 
            tmp[i++] = nums[cur2++];
        //将排序完成的数拷贝回原数组
        System.arraycopy(tmp, 0, nums, left, right - left + 1);
    }
}

非递归版

class Solution {
	// 全局变量节省空间
    int[] temp = null;

    public int[] sortArray(int[] nums) {
    	// 归并排序(非递归)
        temp = new int[nums.length];
        // Nor 表示非递归
        mergeSortNor(nums);
        return nums;
    }

    private void merge(int[] arr, int left, int right, int mid) {
        int s1 = left, s2 = mid + 1;
        // int[] temp = new int[right - left + 1];//开辟临时数组
        int k = 0;//temp的初始下标
        while (s1 <= mid && s2 <= right)// 将较小的数依次插入 temp
            if (arr[s1] <= arr[s2])
                temp[k++] = arr[s1++];
            else
                temp[k++] = arr[s2++];
        // 防止有数未插入
        while (s1 <= mid)
            temp[k++] = arr[s1++];
        while (s2 <= right)
            temp[k++] = arr[s2++];
        System.arraycopy(temp, 0, arr, left, right - left + 1);
    }

    public void mergeSortNor(int[] arr) {
        int len = arr.length;
        int gap = 1;//步长用来划分合并数组
        while (gap < len) {
            for (int i = 0; i < len; i += 2 * gap) {
                int left = i, mid = left + gap - 1, right = mid + gap;
                // 解决步长过大的问题(即步长大+一部分数组大于整体数组长度)
                if (mid >= len)
                    mid = len - 1;
                if (right >= len)
                    right = len - 1;
                merge(arr, left, right, mid);
            }
            gap *= 2;// 步长不断扩大
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值