文字描述

  假设初始序列有n个记录,则可看成是n个有序的字序列,每个字序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,…, 如此重复,直到得到一个长度为n的有序序列为止,这种排序方法称为2-路归并排序。

示意图

算法分析

  2-路归并排序的时间复杂度为nlogn;

  2-路归并排序需要至少同待排序序列同等大小的辅助空间;

  与快速排序和堆排序相比,归并排序最大特点就是,它是一种稳定的排序方法。

  在一般情况下,2-路归并排序,尤其是递归形式的,很少在内部排序中使用,一般用于外部排序,因为反复的自身函数的调用,容易引起栈溢出。

代码实现

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <math.h>
  4 /*
  5  * double log2(double x);    以2为底的对数
  6  * double ceil(double x);    取上整
  7  * double floor(double x);    取下整
  8  * double fabs(double x);    取绝对值
  9  */
 10
 11 #define DEBUG
 12
 13 #define EQ(a, b) ((a) == (b))
 14 #define LT(a, b) ((a) <  (b))
 15 #define LQ(a, b) ((a) <= (b))
 16
 17 //定义顺序表中结点个数的最大值
 18 #define MAXSIZE  100
 19 //定义无穷大INF的值
 20 #define INF         1000000
 21
 22 //定义结点中的关键字类型为int
 23 typedef int KeyType;
 24 //定义结点中除关键字外的附件信息为int
 25 typedef char InfoType;
 26
 27 //待排序的结点的结构体
 28 typedef struct{
 29     //结点中的关键字
 30     KeyType key;
 31     //结点中的除关键字外的附加信息
 32     InfoType otherinfo;
 33 }RedType;
 34
 35 //顺序表的结构体
 36 typedef struct{
 37     //顺序表中待排序的结点
 38     RedType r[MAXSIZE+1];
 39     //顺序表中待排序的结点个数
 40     int length;
 41 }SqList;
 42
 43 //依次打印顺序表中结点的信息
 44 void PrintList(SqList L){
 45     int i = 0;
 46     printf("下标值:");
 47     for(i=0; i<=L.length; i++){
 48         printf("[%d] ", i);
 49     }
 50     printf("\n关键字:");
 51     for(i=0; i<=L.length; i++){
 52         if(EQ(L.r[i].key, INF)){
 53             printf(" %-3c", '-');
 54         }else{
 55             printf(" %-3d", L.r[i].key);
 56         }
 57     }
 58     printf("\n其他值:");
 59     for(i=0; i<=L.length; i++){
 60         printf(" %-3c", L.r[i].otherinfo);
 61     }
 62     printf("\n\n");
 63     return ;
 64 }
 65
 66 //将有序的SR[i,...,m]和SR[m+1,...,n]归并为有序的TR[i,...,n]
 67 void Merge(RedType SR[], RedType TR[], int i, int m, int n)
 68 {
 69     int j = 0, k =0;
 70     //将SR中记录由小到大地归并到TR
 71     for(j=m+1, k=i; i<=m && j<=n; ++k){
 72         if(LQ(SR[i].key, SR[j].key)){
 73             TR[k] = SR[i++];
 74         }else{
 75             TR[k] = SR[j++];
 76         }
 77     }
 78     //将剩余的SR[i,...,m]复制到TR
 79     for(; i<=m; i++){
 80         TR[k++] = SR[i];
 81     }
 82     //将剩余的SR[j,...,n]复制到TR
 83     for(; j<=n; j++){
 84         TR[k++] = SR[j];
 85     }
 86 }
 87
 88 //将SR[s,...,t]归并排序为TR1[s,...,t]
 89 void MSort(RedType SR[], RedType TR1[], int s, int t)
 90 {
 91     if(s == t){
 92         TR1[s] = SR[s];
 93     }else{
 94         //将SR[s,...,t]平分为SR[s,...,m]和SR[m+1,...,t]
 95         int m = (s+t)/2;
 96         RedType TR2[MAXSIZE+1];
 97         //递归地将SR[s,...,m]归并为有序的TR2[s,...,m]
 98         MSort(SR, TR2, s, m);
 99         //递归地将SR[m+1,...,t]归并为有序的TR2[m+1,...,t]
100         MSort(SR, TR2, m+1, t);
101         //将TR2[s,...,m]和TR2[m+1,...,t]归并到TR1[s,...,t]
102         Merge(TR2, TR1, s, m, t);
103     }
104 }
105
106 //对顺序表L作2-路归并排序
107 void MergeSort(SqList *L)
108 {
109     MSort(L->r, L->r, 1, L->length);
110 #ifdef DEBUG
111     printf("对该数据作2-路归并排序后:\n");
112     PrintList(*L);
113 #endif
114 }
115
116 int  main(int argc, char *argv[])
117 {
118     if(argc < 2){
119         return -1;
120     }
121     SqList L;
122     int i = 0;
123     for(i=1; i<argc; i++){
124         if(i>MAXSIZE)
125             break;
126         L.r[i].key = atoi(argv[i]);
127         L.r[i].otherinfo = 'a'+i-1;
128     }
129     L.length = (i-1);
130     L.r[0].key = 0;
131     L.r[0].otherinfo = '0';
132     printf("输入数据:\n");
133     PrintList(L);
134     //对顺序表L最2-路归并排序
135     MergeSort(&L);
136     return 0;
137 }

2-路归并排序

运行

转载于:https://www.cnblogs.com/aimmiao/p/9392008.html

内部排序-归并排序-2-路归并排序相关推荐

  1. C语言实现归并排序——2路归并排序

    C语言实现归并排序 文章目录 C语言实现归并排序 2路归并排序算法 1.定义动态数组 2.初始化动态数组 3.归并操作 4.归并排序算法实现 项目完整代码 运行效果图 2路归并排序算法 1.定义动态数 ...

  2. 10-10-归并排序-内部排序-第10章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第10章  内部排序 - 归并排序 --<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源 ...

  3. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  4. 掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)...

    掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等). 数组高级以及Arrays(掌握) 排序方法 空间复杂度 时间复杂度 稳定性 插 入 排 序 ...

  5. 10种排序算法比较(直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、归并排序、基数排序、折半插入排序、2路插入排序)

    本文(所有排序算法代码+综合比较代码)链接:https://download.csdn.net/download/qq_39932172/11217572 一.比较目的: 由于<数据结构> ...

  6. 九大内部排序算法(快速排序、归并排序、堆排序、希尔排序、基数排序)

    排序(Sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列. 文章目录 由于待排序的记录数量不同,使得排序过程中涉及的存储器 ...

  7. K路归并排序与败者树

    一.大文件的排序问题 在我们日常开发中有时候会遇到这样一个问题,有一个文件大小为10GB,现在要为里面的数据进行排序,而计算机的内存只有1GB,如何对这10GB的数据进行排序呢? 由于内存空间只有1G ...

  8. 数据结构——排序:插入排序、选择排序、交换排序、归并排序、基数排序

    排序 内部排序:数据量不大,在内存中可以完成排序. 外部排序:借助外存.把数据文件分成若干块,涉及内外存数据的转换.存储器的管理等. 稳定排序:能保证排序前两个相等的数其在序列的前后位置顺序和排序后它 ...

  9. 快速排序算法_经常用到的的排序(快速排序和归并排序)简单的计算机算法学习...

    1.快速排序 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1960年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的 ...

最新文章

  1. windows10中 git 本地仓库的使用
  2. Python 技术篇-用pytesseract库进行图像识别之环境配置
  3. c++反射机制(vcl实现),mfc可依样实现
  4. 每日程序C语言31-auto的使用
  5. linux挂载4t硬盘用不了,centos7挂载新加4T硬盘到/home目录
  6. ios系统python编译器_MacBook如何安装Python编译器-百度经验
  7. path png转svg_如何将jpg或png图像转换成svg并保存?
  8. linux less 带颜色,less中color函数字体颜色计算
  9. 2015年1月微信上线原创声明功能:智能添加原创标识 转载自动注明出处
  10. msconfig蓝屏_电脑msconfig改动后蓝屏怎么修复
  11. c# dataset 和DataGridView的绑定详细
  12. 关于加强销售费用管理的探讨
  13. Ubuntu命令行安装Google浏览器
  14. ORA-03113 错误分析与解决
  15. 「雕爷学编程」Arduino动手做(23)——矩形脉冲发生器
  16. Git强拉远程代码覆盖本地代码
  17. Maven Dependency设置,详解! 1
  18. 怎样开启计算机的隐藏功能音乐,只要开启vivo手机的这一隐藏功能,就让音乐效果翻倍...
  19. 数据恢复工具什么牌子的好
  20. 学不可以已——我一年Java之路的回顾,反思以及展望

热门文章

  1. 《学习记录》“Python”输入1-4判断季度有那几个月
  2. 跨年倒计时软件app哪个好 2022年跨年倒计时软件推荐云便签
  3. EXSI-NFS实验
  4. 2022-02-15每日刷题打卡
  5. PHP实现量化交易,量化交易干货丨如何使用DolphinDB计算K线
  6. 懂代码且抢手的全栈设计师是怎样炼成的?
  7. harmony应用主题样式
  8. 吕建伟:不要把自己的公司定位为软件公司
  9. 全新领域——前端处理高并发
  10. 动态规划状态机模型:股票买卖I