归并排序

归并排序(Merge Sort)

  1. 基本思想
  • 建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
  • 作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
    • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法)
    • 自下而上的迭代
  1. 算法步骤
  • 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  • 设置两个指针,初始位置为两个已经排序序列的起始位置
  • 比较两个指针指向元素大小,选择较小的元素存放到新空间,并移动指针指向下一位置
  • 重复,直到某一指针到达序列尾部
  • 将另一序列剩下元素直接存入新序列尾部
    例如:


    mergeSort.jpg
  1. 动图演示


    mergeSort.gif
  2. 代码实现
    使用自上而下的递归法实现,分三个小方法,在代码中有详细注释,此处不多罗列

    public static void mergeSort(int[] arr) {
        if (null == arr || arr.length < 1) return;

        sort(arr, 0, arr.length - 1);
    }
    /**
     * 归并排序 主方法 - 递归实现
     * @param arr 主数组
     * @param start 排序起始索引
     * @param end 排序终止索引
     */
    public static void sort(int[] arr, int start, int end) {
        if (start == end) return;

        int mid = (start + end) / 2;
        // 左区间递归
        sort(arr, start, mid);
        // 右区间递归
        sort(arr, mid + 1, end);
        // 合并
        merge(arr, start, end, mid);
    }
    /**
     * 数组合并
     * @param arr
     * @param left 左索引
     * @param right 右索引
     * @param mid 中间索引
     */
    public static void merge(int[] arr, int left, int right, int mid) {
        // [left, mid],[mid+1, right]
        int[] temp = new int[right - left + 1];

        // 定义数组遍历的左起始位置,和右起始位置
        int ls = left, rs = mid + 1;
        int tempIndex = 0;
        while (ls <= mid && rs <= right) {
            if (arr[ls] < arr[rs]) {
                temp[tempIndex] = arr[ls];
                ls++;
            } else {
                temp[tempIndex] = arr[rs];
                rs++;
            }
            tempIndex++;
        }

        while (ls <= mid) {
            temp[tempIndex] = arr[ls];
            ls++;
            tempIndex++;
        }

        while (rs <= right) {
            temp[tempIndex] = arr[rs];
            rs++;
            tempIndex++;
        }

        // 将排序好的临时数组,写回原需排序数组
        for (int i = 0; i < temp.length; i++) {
            arr[left + i] = temp[i];
        }
    }
  1. 时间复杂度分析
    归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)

优化

可使用自下而上的迭代法实现,迭代的性能是会优于递归的,并且递归太深也存在内存溢出风险。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容