美文网首页
《算法》2.2-归并排序

《算法》2.2-归并排序

作者: 不会code的程序猿 | 来源:发表于2017-07-05 16:54 被阅读51次

1. 基本思想

①Divide array into two halves.
②Recursively sort each half.
③Merge two halves.
将数组分成两部分,两部分分别排好序,最后将两个有序的子数组整合成一个有序的数组。


归并排序

注意:input数组是归并排序需要的额外空间。results数组是输入数组排序后的结果。

    // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
    private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
        // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
        assert isSorted(a, lo, mid);
        assert isSorted(a, mid+1, hi);
        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = a[k]; 
        }
        // merge back to a[]
        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if      (i > mid)              a[k] = aux[j++];
            else if (j > hi)               a[k] = aux[i++];
            else if (less(aux[j], aux[i])) a[k] = aux[j++];
            else                           a[k] = aux[i++];
        }
        // postcondition: a[lo .. hi] is sorted
        assert isSorted(a, lo, hi);
    }

2. 自顶向下的归并排序

  1. Code
 // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
    private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, aux, lo, mid);
        sort(a, aux, mid + 1, hi);
        merge(a, aux, lo, mid, hi);
    }
//调用方法   
    public static void sort(Comparable[] a) {
        Comparable[] aux = new Comparable[a.length];
        sort(a, aux, 0, a.length-1);
        assert isSorted(a);
    }
  1. Example
    top-down归并排序
    要理解递归调用的次序:

    3.分析
    ①长度为N的数组使用归并排序最多需要NlgN次比较。每次归并最多N次比较,最少N/2次比较。
    C (N) ≤ C (⎡N / 2⎤) + C (⎣N / 2⎦) + N for N > 1, with C (1) = 0

    ②长度为N的数组自顶向下归并排序最多需要访问数组6NlgN次。
    每次归并需要aux[k] = a[k]最多访问2N次数组,每次归并最多进行N次比较,每次比较访问2个元素,比较共2N次访问数组,最后将排好序的结果拷贝到原始数组中a[k] = aux[XX]需要2N次访问数组。
    ③归并排序需要N个额外的存储空间。

3. 自底向上的归并排序

  1. Code
 public static void sort(Comparable[] a) {
        int n = a.length;
        Comparable[] aux = new Comparable[n];
        //len代表子数组的大小
        for (int len = 1; len < n; len *= 2) {
            for (int lo = 0; lo < n-len; lo += len+len) {
                int mid  = lo+len-1;
                int hi = Math.min(lo+len+len-1, n-1);
                merge(a, aux, lo, mid, hi);
            }
        }
        assert isSorted(a);
    }
  1. Example
    bottom up归并排序

4. 排序算法的复杂度

没有任何基于比较的算法能够保证使用少于lg(N!)~NlgN次比较将长度为N的数组排序。
排序树:假设有N=3,a[0],a[1],a[2]三个元素。


排序树

①一定有N!个叶子结点,每个结点代表了一种排序的结果。
②从根节点到叶子结点的一条路上的内部结点的数量是某种输入情况下算法的比较次数。
③从根节点到叶子结点路径有多长?最坏的输入下高度为h的二叉树最多有2^h个叶子结点。


完全二叉树
最坏情况下的比较次数就是h,任意算法的比较次数至少是lgN!~NlgN

相关文章

  • 《算法》2.2-归并排序

    1. 基本思想 ①Divide array into two halves.②Recursively sort e...

  • 2018-06-30

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

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

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

  • 排序算法之归并排序

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

  • 归并排序

    图解排序算法(四)之归并排序 基本思想 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用...

  • 归并排序

    归并排序 这个排序算法是建立在归并操作上的一种有效的排序算法,算法主要采用分治法,归并排序的算法复杂度为O(n*l...

  • 第三章:高级排序算法

    归并排序算法(mergeSort) 算法思想:Python使用函数实现: 自底向上的归并排序算法 算法思想:Pyt...

  • 算法入门——归并排序、希尔排序

    上篇文章我们学习了算法入门——堆排序,这篇文章我们学习算法入门——归并排序、希尔排序。 归并排序 归并排序是将一个...

  • 归并算法

    归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。归并算法的中心是归并两...

  • web开发需要知道的几个算法

    算法分类 快速排序算法 深度优先算法 广度优先算法 堆排序算法 归并排序算法

网友评论

      本文标题:《算法》2.2-归并排序

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