归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将这个序列分割成一个一个已经排好序的子序列,然后再利用归并的方法将一个个的子序列合并成排序好的序列。分割和归并的过程可以看下面的图例。

1、算法基本思路
     设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:a[start..mid],a[mid+1..end],先将它们合并到一个局部的暂存向量r(相当于输出堆)中,待合并完成后将r复制回a[start..end]中。

(1)合并过程
     合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较a[i]和a[j]的关键字,取关键字较小的记录复制到r[p]中,然后将被复制记录的指针i或j加1,以及指向复制位置的指针p加1。
     重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录依次复制到r中即可。

(2)动态申请R1
     实现时,R1是动态申请的,因为申请的空间可能很大,故须加入申请空间是否成功的处理。
2、自顶向下的方法(归并排序)
     采用分治法进行自顶向下的算法设计,形式更为简洁。

(1)分治法的三个步骤
     设归并排序的当前区间是a[start..end],分治法的三个步骤是:
①分解:将当前区间一分为二,即求分裂点
                
②求解:递归地对两个子区间a[start..mid]和R[mid+1..end]进行归并排序;
③组合:将已排序的两个子区间R[start..mid]和R[mid+1..end]归并为一个有序的区间R[start..end]。
  递归的终结条件:子区间长度为1(一个记录自然有序)。

整体程序如下:

#include<iostream>
#include<stdlib.h>
#define error printf
using namespace std;
void Merge(int *a,int start,int mid,int end);
void Merge_sort(int *a,int start,int end);
int main()
{
      int i,a[1000],start,end;
     cout<<"Please input start and end:";
     cin>>start>>end;
     cout<<"Please input "<<end+1<<" numbers: ";
     for(i=0;i<end+1;i++)
           cin>>a[i];
     Merge_sort(a,start,end);
      cout<<"The result of resorted: ";
     for(i=0;i<end+1;i++)
           cout<<a[i]<<' ';
}
void Merge(int a[],int start,int mid,int end)
{//将两个有序的子文件a[start..mid)和R[mid+1..end]归并成一个有序的
        int i=start,j=mid+1,p=0;
        int *r;
        r=(int *)malloc((end-start+1)*sizeof(int));
        if(!r)//申请空间失败
        error("insufficient memory available");
        while(i<=mid&&j<=end)//两子文件非空时取其小者输出到r[p]上
        r[p++]=(a[i]<a[j])?a[i++]:a[j++];
        while(i<=mid) r[p++]=a[i++];//若第1个子文件非空,则复制剩余记录到r中
        while(j<=end) r[p++]=a[j++];//若第2个子文件非空,则复制剩余记录到r中

for(i=start,p=0;i<=end;p++,i++)
       a[i]=r[p];//归并完成后将结果复制回a[start..end]

}
void Merge_sort(int *a,int start,int end)
{
    int mid;
    if(start<end)//将两个有序的子文件a[start..mid)和R[mid+1..end]归并成一个有序的
    {
        mid=(end+start)/2;//分解
        Merge_sort(a,start,mid);//递归地对a[start..mid]排序
        Merge_sort(a,mid+1,end);//递归地对a[mid+1..end]排序
        Merge(a,start,mid,end);//组合,将两个有序区归并为一个有序区
     }
}

数据结构与算法之七归并排序相关推荐

  1. 数据结构与算法之归并排序

    数据结构与算法之归并排序 目录: 归并排序介绍 归并排序思想示意图 代码实现 1. 归并排序介绍 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-a ...

  2. 数据结构排序算法之归并排序(c语言实现)

    博主身为大二萌新,第一次学习数据结构,自学到排序的时候,对于书上各种各样的排序算法顿觉眼花缭乱,便花了很长的时间尽力把每一个算法都看懂,但限于水平有限,可能还是理解较浅,于是便将它们逐个地整理实现出来 ...

  3. 数据结构与算法详解(含算法分析、动图图解、Java代码实现、注释解析)

    数据结构和算法的重要性 算法是程序的灵魂,优秀的程序可以在海量数据计算时,依然保持高速计算 数据结构和算法的关系: 程序 = 数据结构 + 算法 数据结构是算法的基础, 换言之,想要学好算法,需要把数 ...

  4. 数据结构和算法之排序一:归并排序

    我们不得不承认一个事实,java学习过程中如果我们掌握了各种编程手段和工具,确实可以做一些开发,这就是一些培训机构敢告诉你几个月就能掌握一门语言的原因.但是随着时间的发展,我们总会感觉,这一类人如果不 ...

  5. 数据结构与算法:十大排序算法之归并排序

    数据结构与算法:十大排序算法之归并排序 package TopTenSortingAlgorithms;/*** 归并排序:Java** @author skywang* @date 2014/03/ ...

  6. 数据结构与算法XS班-左程云第八节课笔记(归并排序和快速排序)

    第8节 归并排序和快速排序 ##这是数据结构与算法新手班-左程云第八节课的笔记## 归并排序 归并排序实际上是一个很经典的排序方法,时间复杂度o(N*logN). 递归版本(图解排序算法(四)之归并排 ...

  7. 【数据结构与算法】高级排序(希尔排序、归并排序、快速排序)完整思路,并用代码封装排序函数

    本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...

  8. 资料分享:送你一本《数据结构与算法JavaScript描述》电子书!

    数据结构 是掌握计算机编程必须具备的技能.通常情况下,我想掌握一门编程语言所用的方法就是利用这门语言把数据结构中线性表.栈.队列.字符串.动态数字.整数集合.树.图.搜索.排序等涉及的算法全部写一遍. ...

  9. 数据结构与算法的八股文自述(持续更新)

    数据结构与算法的八股文自述 1.1 排序算法 冒泡排序: 冒泡排序只会操作相邻的两个数据.每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求.如果不满足就让它俩互换.一次冒泡会让至少一个 ...

最新文章

  1. Java实现简单的RPC框架
  2. 北航计算机考博C语言真题_北京航空航天大学计算机考研:严厉的老父亲,教会你本事,本科非211以上就不要去了...
  3. Slack推安全企业加密管理可轻易用密钥控制数据
  4. LeetCode-726. 原子的数量(python2)
  5. 【莓控】黑莓GOOGLE MAPS(GPS软件)-转贴
  6. 一文看懂深度学习新王者「AutoML」:是什么、怎么用、未来如何发展?
  7. java判断两个矩形是否相交_判断矩形相交以及求出相交的区域
  8. latex中png、pdf和eps格式的图片文件转换
  9. Exercise39: python字典(访问,操作,list(), dirt.items(), dirt.get() )
  10. java获取文件名格式 / java获取文件名后缀
  11. 如何禁用计算机休眠,电脑如何关闭休眠功能,教你电脑如何关闭休眠功能
  12. 计算机网络安全及故障谢辞,计算机网络安全初探.pdf
  13. PDF如何转换成EPUB格式
  14. Flex使用ribbit.com的服务给手机发送短信SMS
  15. JS简单实现鼠标跟随
  16. 【Spring AOP】@Aspect结合案例详解(二): @Pointcut使用@within和within(已附源码)
  17. Home Assistant入门1-1:在树莓派上安装官方系统
  18. 2019年,SEO关键词KPI考核指标有哪些?
  19. Hadoop组成及各组件架构概述
  20. stm32f407VE+enc28j60+lwip2.0.2

热门文章

  1. 电脑文件夹加密软件_上海靠谱电脑资料加密软件解决方案
  2. 郑州大学Oracle期末,郑州大学软件学院2011到2012学年第二学期Oracle期末试卷.doc
  3. python布局管理数据_利用python创建窗口-布局管理器(五)
  4. esxi6.0开启网络UI管理界面
  5. php mysql 多行_php-更新MySQL中的多行而没有循环
  6. IPLATUI----GRID状态
  7. 显示器与服务器连接线叫什么,连接显示器和主机的线叫什么
  8. matlab在运筹学,MATLAB在运筹学(单纯形法)教学中的应用
  9. 电脑发短信_让电脑自动给老婆发短信?!这个懒到极致的大神,我是服了...
  10. Java使用swagger时显示实体类注解问题