排序-归并排序

简介

归并排序(merge sort)是一种采用了 分治 思想的排序算法。

工作原理

归并排序分为三个步骤:

  1. 将数列划分为两部分;
  2. 递归地分别对两个子序列进行归并排序;
  3. 合并两个子序列。
    不难发现,归并排序的前两步都很好实现,关键是如何合并两个子序列。注意到两个子序列在第二步中已经保证了都是有序的了,第三步中实际上是想要把两个 有序 的序列合并起来。

性质

归并排序是一种稳定的排序算法。

归并排序的最优时间复杂度、平均时间复杂度和最坏时间复杂度均为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

归并排序的空间复杂度为 O ( n ) O(n) O(n)

代码实现

    public static void mergeSort(int[] arr) {
        if (arr.length == 0) {
            return;
        }
        int[] result = mergeSort(arr, 0, arr.length - 1);
        // 将结果拷贝到 arr 数组中
        for (int i = 0; i < result.length; i++) {
            arr[i] = result[i];
        }
    }


    /**
     * 对 arr 的 [start, end] 区间归并排序
     *
     * @param arr
     * @param start
     * @param end
     * @return
     */
    private static int[] mergeSort(int[] arr, int start, int end) {
        // 只剩下一个数字,停止拆分,返回单个数字组成的数组
        if (start == end) {
            return new int[]{arr[start]};
        }
        int middle = (start + end) / 2;
        // 拆分左边区域
        int[] left = mergeSort(arr, start, middle);
        // 拆分右边区域
        int[] right = mergeSort(arr, middle + 1, end);
        // 合并左右区域
        return merge(left, right);
    }

	/**
     * 将两个有序数组合并为一个有序数组
     */
    private static int[] merge(int[] arr1, int[] arr2) {
        int[] result = new int[arr1.length + arr2.length];
        int index1 = 0, index2 = 0;
        while (index1 < arr1.length && index2 < arr2.length) {
            if (arr1[index1] <= arr2[index2]) {
                result[index1 + index2] = arr1[index1];
                index1++;
            } else {
                result[index1 + index2] = arr2[index2];
                index2++;
            }
        }
        // 将剩余数字补到结果数组之后
        while (index1 < arr1.length) {
            result[index1 + index2] = arr1[index1];
            index1++;
        }
        while (index2 < arr2.length) {
            result[index1 + index2] = arr2[index2];
            index2++;
        }
        return result;
    }

补充

归并排序就是个二叉树的后序遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值