美文网首页
经典排序算法系列4-归并排序

经典排序算法系列4-归并排序

作者: xgangzai | 来源:发表于2019-11-22 13:40 被阅读0次

Merging Sort - 归并排序

需求

对N个整数升序排序

思路

把数组分成两部分(递归均分,直至每部分只有一个元素),每部分先排序,然后合并有序的两部分。利用到了分治思想,一般来讲,分治思想需要递归编程来实现。

算法评判

  • 时间复杂度

    O(NlogN)

  • 空间复杂度

    O(N)

    只需要常量级的辅助空间,所以也叫原地排序

  • 稳定性

    结论:稳定

实现代码如下

public void sort(int[] arr) {
    int[] result = new int[arr.length];
    mergeRecursive(arr, result, 0, arr.length - 1);
}

//递归
private void mergeRecursive(int[] arr, int[] result, int start, int end) {
    if (start >= end) {
        return;
    }

    //对半分
    int len = end - start;
    int middle = len >> 1;
    int start1 = start;
    int end1 = start1 + middle;
    int start2 = end1 + 1;
    mergeRecursive(arr, result, start1, end1);
    mergeRecursive(arr, result, start2, end);

    //合并两个组到result中
    int k = start;
    while (start1 <= end1 && start2 <= end) {
        if (arr[start2] < arr[start1]) {
            result[k++] = arr[start2++];
        } else {
          //如果后部分不小于前部分,可能的情况是两个元素相等,优先取前部分的
            result[k++] = arr[start1++];
        }
    }

    //拷贝剩余的
    if (start1 <= end1) {
        System.arraycopy(arr, start1, result, k, end1 + 1 - start1);
    }
    if (start2 <= end) {
        System.arraycopy(arr, start2, result, k, end + 1 - start2);
    }

    //将合并好的拷贝到原数组中
    System.arraycopy(result, start, arr, start, end + 1 - start);

}

关于稳定性,因为在合并两个有序数组时,当两个元素相等,优先取前部分中的元素,所以归并排序是稳定的。

这种思路是从上而下,还有一种自下而上的思路,从每个子序只有一个元素开始,每两两合并,直至最终合并成一个序列,代码实现如下

private void sortMerge(int[] arr) {
    int[] orderedArr = new int[arr.length];
    //i 每组数量
    for (int i = 2; i < arr.length * 2; i *= 2) {
        //j 组数
        for (int j = 0; j < (arr.length + i - 1) / i; j++) {
            int left = i * j;
            //mid 是右半部分的第一个元素下标
            int mid = left + i / 2 >= arr.length ? (arr.length - 1) : (left + i / 2);
            int right = i * (j + 1) - 1 >= arr.length ? (arr.length - 1) : (i * (j + 1) - 1);
            int start = 0, l = left, m = mid;
            //因为mid是右半部分的第一个元素下标,所以等号在右半部分
            while (l < mid && m <= right) {
                if (arr[m] < arr[l]) {
                    orderedArr[start++] = arr[m++];
                } else {
                  //如果相等,优先取前部分的元素,保证稳定性
                    orderedArr[start++] = arr[l++];
                }
            }
            while (l < mid) {
                orderedArr[start++] = arr[l++];
            }
            while (m <= right) {
                orderedArr[start++] = arr[m++];
            }
            System.arraycopy(orderedArr, 0, arr, left, right - left + 1);

        }
    }
}

问题:时间复杂度计算

相关文章

  • 排序算法

    小胡子哥:聊一聊排序算法白话经典算法系列之五 归并排序的实现

  • 2018-06-30

    排序算法之归并排序 归并排序算法是排序算法中的经典算法之一,其核心思想是利用归并的思想实现的排序方法,该算法采用经...

  • 排序算法之归并排序

    归并排序(Merge Sort) 归并排序是利用归并的思想实现排序的方式,该算法采用的是经典的分治算法 归并排序过...

  • 3.2-选择排序-堆排序

    参考链接 选择排序:堆排序(Heap Sort) 白话经典算法系列之七 堆与堆排序 堆排序与快速排序,归并排序一样...

  • 用 Python 实现十大经典排序算法

    今天,详细的跟大家分享下 10 种经典排序算法。 10种经典排序算法包括冒泡排序、选择排序、快速排序、归并排序、堆...

  • 归并排序&快速排序

    归并排序 利用归并的思想实现排序方法,该算法采用经典的分治策略,分而治之。 代码实现 基础设置 归并排序 —— 非...

  • 数据结构--归并排序与基数排序

    一、归并排序归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-a...

  • Algorithm -- 排序算法

    单链表十大经典排序算法冒泡排序选择排序插入排序归并排序快速排序堆排序计数排序桶排序 1. 十大经典排序算法 十大经...

  • < 排序大全系列 > 归并排序总结

    < 排序大全系列 > 归并排序总结: 导言: 在学习排序算法之前,我几乎所有的排序算法用的都是“冒泡排序法”,当...

  • java实现快速排序、归并排序、希尔排序、基数排序算法...

    快速排序算法 归并排序算法 希尔排序算法 基数排序算法

网友评论

      本文标题:经典排序算法系列4-归并排序

      本文链接:https://www.haomeiwen.com/subject/qlafwctx.html