排序算法总结(7)--归并排序

原创 2017年05月23日 10:41:45

一、简介

理解归并排序有两种思路:1、自顶向下化整为零,2、自底向上循序渐进
1、自顶向下:将无序序列平均分成两部分,分别对这两部分排序,然后合并。这样将一个大问题分解成两个小问题。同理,如何对两个小部分进行排序?分别将它们分解为更小的问题。在这个算法中,分解问题很简单,主要是如何合并两个小序列为一个有序序列。
2、自底向上:首先将长度为n的序列分解成n个长度为1的序列,成对的合并它们,成为n/2个长度为2的有序序列。然后再成对合并,直到合并成原来的长度。这里的关键在于合并序列。
所以归并排序的关键在于合并。如何合并两个有序序列呢?给定两个序列A[p,…q]和A[q+1,…r],都是已经排序好的。首先将两个子序列复制,有两个指针i,j,分别指向复制后的两个序列的起始位置。从两个指针指向的元素中选择较小的元素,放入A[p,…,r]中,对应子序列上的指针向后移。直到其中一个序列遍历完毕,将另一个序列剩余的元素全部放入A[p,…,r]。

二、代码实现

2.1 合并

伪代码

megre(array,p,q,r)
        n1=q-p+1;
        n2=r-q;
        letL[0,...,n1] and R[0,...,n2]是两个新的数组
        将 array[p,...,q]复制到L,array[q+1,...,r]复制到R
        且arrarR和arrayL中最后一个数是Integer.MAX_VALUE
        //合并开始
        i=0;
        j=0;
        for k=p to r
            if L[i]<=R[j]
                array[k]=L[i];
                i++;
            else
                array[k]=R[j];
                j++;

在复制两个子序列时,在他们最后分别放上一个无穷大的值作为哨兵,用于简化代码。当指针指向其中一个哨兵时,他不可能是较小的值,除非两个指针都指向哨兵,此时所有元素已经合并完毕。

代码实现

public static void megre(int[] array,int p,int q,int r){
        int n1=q-p+1;
        int n2=r-q;
        int[] arrayL=new int[n1+1];
        int[] arrayR=new int[n2+1];
        for(int i=0;i<n1;i++){
            arrayL[i]=array[p+i];
        }


        arrayL[n1]= Integer.MAX_VALUE;

        for(int i=0;i<n2;i++){
            arrayR[i]=array[q+1+i];
        }
        arrayR[n2]= Integer.MAX_VALUE;

        int i=0;
        int j=0;
        for(int k=p;k<=r;k++){
            if (arrayL[i]<=arrayR[j]){
                array[k]=arrayL[i];
                i++;

            }else{
                array[k]=arrayR[j];
                j++;
                }
            }
        }

2.2 自顶向下的归并排序

public static void topMegreSort(int[] array,int p,int r){
        if (p<r){
            int q=(p+r)/2;
            topMegreSort(array,p,q);
            topMegreSort(array,q+1,r);
            megre(array,p,q,r);
        }
    }

2.3 自底向上的归并排序

public static void bottomMegreSort(int [] array){
        int n=array.length;
        for(int sz=1;sz<n;sz*=2){
            for(int i=0;i<n-sz;i+=sz+sz){
                megre(array,i,i+sz-1,Math.min(i+sz+sz-1,n-1));
            }
        }
    }

三、递归方程

自顶向下的归并排序应用了递归的思想,如何从递归的算法中分析时间复杂度呢?我们可以使用递归方程或递归式来描述其运行时间,该方程根据在较小输入上的运行时间来描述在规模为n的问题上的总运行时间。然后通过数学工具求解该递归式给出算法的时间复杂度。例如,在归并排序中,假设T(n)是问题规模为n时的运行时间,将原问题分解为2个规模为n/2的子问题,每个问题的运行时间为T(n/2)分解和合并所需的时间是O(n),所以
这里写图片描述
如何求解用递归方程表示的时间复杂度?参见http://www.cnblogs.com/python27/archive/2011/12/09/2282486.html
主要介绍了代入法,迭代法,公式法,母函数法,差分方程法。

四、注意事项

1、归并排序的空间复杂度并不是O(1),在合并的过程中,需要辅助空间
2、归并排序直到递归结束才能确定所有元素的最终位置。

【算法总结】归并排序总结

【前言】 归并排序的思想是,将一个数组划分成为可以轻易排序的最小部分(最小部分的标准通常是1个数或者两个数),对最小数组排好序后,向上合并排序数组(向上合并排序通常需要额外空间,譬如:现在两个排好序的...
  • cdnight
  • cdnight
  • 2013年09月16日 11:16
  • 1111

归并排序算法解析

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。 一次归并算法 1、基本思路 ...
  • yousir1988
  • yousir1988
  • 2012年06月25日 17:38
  • 5482

算法系列(四)排序算法中篇--归并排序和快速排序

在算法系列(三)排序算法上篇 一文中,介绍了冒泡排序,插入排序和选择排序算法。这篇文章继续讲解排序算法。 概述 冒泡排序,插入排序和选择排序算法这些算法的时间复杂度都是O(N^2),是否有更高效的排序...
  • robertcpp
  • robertcpp
  • 2016年05月30日 23:04
  • 3384

归并排序 图解算法过程

归并排序,图解,详细过程。
  • collonn
  • collonn
  • 2013年12月26日 14:09
  • 7790

排序算法(2)——归并排序

归并排序(Merge Sort)    (1)算法思想              归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解...
  • tmylzq187
  • tmylzq187
  • 2016年07月03日 17:48
  • 19467

排序算法系列:归并排序算法

上一篇我们说了一个非常简单的排序算法——选择排序。其复杂程序完全是冒泡级的,甚至比冒泡还要简单。今天要说的是一个相对比较复杂的排序算法——归并排序。复杂的原因不仅在于归并排序分成了两个部分进行解决问题...
  • u013761665
  • u013761665
  • 2016年05月27日 16:32
  • 10680

数据结构——归并排序算法

昨天说了快速排序,今天来讲一讲归并排序:什么是归并?归并:将两个或两个以上的有序表组合成一个新有序表。归并操作的步骤: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 设定两个指...
  • u013271921
  • u013271921
  • 2015年05月26日 14:33
  • 7132

常用排序算法——归并排序法

归并排序采用的是分治思想,将数组不断分解为子数组,直到子数组只有一个元素,每次分解对应一个归并函数,归并函数可以将当前分解的两个子数组合并起来。有两种方式可以实现归并排序,第一种是递归方式实现的,代码...
  • girlkoo
  • girlkoo
  • 2013年12月27日 10:11
  • 3286

选择排序和归并排序

选择排序 选择排序的基本思想:每一次在n-i+1(i=1,2,…,n-1)个记录中选取键值最小的记录作为有序序列的第i个记录。 直接选择排序 直接选择排序算法的基本思想:在第i次选择操作中,通过...
  • u013044000
  • u013044000
  • 2015年10月04日 22:03
  • 776

八大排序算法详解——归并排序

基本思想n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果: 初始状态:无序区为R[1..n],有序区为空。 第1趟排序: 在无序区R[1..n]中选出关键字最小的记录R[k],将它与...
  • cy__dream
  • cy__dream
  • 2017年02月08日 20:25
  • 1808
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:排序算法总结(7)--归并排序
举报原因:
原因补充:

(最多只允许输入30个字)