【笔记】归并排序

来源:互联网 发布:股票数据分析员 编辑:程序博客网 时间:2024/05/19 20:45

  归并排序:是又一类不同的排序方法。“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。无论是顺序存储结构还是链表存储结构,都可在O(m+n)的时间量级上实现。

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


这里写图片描述

  一趟归并排序的操作是,调用[n2h]次算法merge将SR.[1…n]中前后相邻且长度为h的有序段进行两两归并,得到前后相邻、长度为2h的有序段,并存放在TR.[1…n]中,整个归并排序需进行[log2n]趟。可见,实现归并排序需和待排记录等数量的辅助空间,其时间复杂度为O(nlogn)

  递归形式的算法在形式上较简洁,但是实用性很差。与快速排序和堆排序相比,归并排序的最大特点是:它是一种稳定的排序方法。但在一般情况下,很少使用2-路归并排序法进行内部排序。

  2-路归并排序中的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列,其算法如下所示。

  • 类型定义
 #include<stdio.h> #define EQ(a,b) ((a)==(b)) #define LT(a,b) ((a)<(b)) #define LQ(a,b) ((a)<=(b)) #define N 7 #define MAXSIZE 20 /* 一个用作示例的小顺序表的最大长度 */ typedef int InfoType; /* 定义其它数据项的类型 */ typedef int KeyType; /* 定义关键字类型为整型 */ typedef struct {   KeyType key; /* 关键字项 */   InfoType otherinfo; /* 其它数据项,具体类型在主程中定义 */ }RedType; /* 记录类型 */ typedef struct {   RedType r[MAXSIZE+1]; /* r[0]闲置或用作哨兵单元 */   int length; /* 顺序表长度 */ }SqList; /* 顺序表类型 */
  • 归并排序函数
 void Merge(RedType SR[],RedType TR[],int i,int m,int n) { /* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] 算法10.12 */   int j,k,l;   for(j=m+1,k=i;i<=m&&j<=n;++k) /* 将SR中记录由小到大地并入TR */     if LQ(SR[i].key,SR[j].key)       TR[k]=SR[i++];     else       TR[k]=SR[j++];   if(i<=m)     for(l=0;l<=m-i;l++)       TR[k+l]=SR[i+l]; /* 将剩余的SR[i..m]复制到TR */   if(j<=n)     for(l=0;l<=n-j;l++)       TR[k+l]=SR[j+l]; /* 将剩余的SR[j..n]复制到TR */ } void MSort(RedType SR[],RedType TR1[],int s, int t) { /* 将SR[s..t]归并排序为TR1[s..t]。算法10.13 */   int m;   RedType TR2[MAXSIZE+1];   if(s==t)     TR1[s]=SR[s];   else   {     m=(s+t)/2; /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */     MSort(SR,TR2,s,m); /* 递归地将SR[s..m]归并为有序的TR2[s..m] */     MSort(SR,TR2,m+1,t); /* 递归地将SR[m+1..t]归并为有序的TR2[m+1..t] */     Merge(TR2,TR1,s,m,t); /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */   } } void MergeSort(SqList *L) { /* 对顺序表L作归并排序。算法10.14 */   MSort((*L).r,(*L).r,1,(*L).length); }
  • 主程序
void print(SqList L) {   int i;   for(i=1;i<=L.length;i++)     printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);   printf("\n"); } void main() {   RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7}};   SqList l;   int i;   for(i=0;i<N;i++)     l.r[i+1]=d[i];   l.length=N;   printf("排序前:\n");   print(l);   MergeSort(&l);   printf("排序后:\n");   print(l); }
  • 测试结果


这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两个月宝宝三天没拉大便怎么办 5个月宝宝3天没拉大便怎么办 4个月宝宝3天没拉大便怎么办 20个月的宝宝大便干燥怎么办 20个月宝宝大便间隔三天怎么办 两个多月的宝宝四天没大便怎么办 两个多月的宝宝几天没大便怎么办 2个月3天没大便怎么办 两个月大的宝宝发烧40度怎么办 两个月大的宝宝感冒了怎么办 四个月宝宝拉水样大便要怎么办 六个月的宝宝咳嗽有痰怎么办 未满月的宝宝大便脓状怎么办 五个月的宝宝总是吃手怎么办 小孩子学数字怎么也学不会怎么办 小孩学数字老是学不会该怎么办 只买了大人票忘买儿童的了怎么办 铝合金滑动门没轨道安纱门怎么办 移门衣柜门与柜体有冶缝隙怎么办 推拉门关门时撞门框声音大怎么办 两岁宝宝夏天不盖被子怎么办 家里有好多会爬的小黑虫怎么办 刚贴的壁纸怎么发霉了怎么办 晚上睡觉一熄灯有许多小虫子怎么办 一岁宝宝夏天爱哭不爱吃饭怎么办 合肥房子卖了户口没地方迁怎么办 忌作灶的日子新房装橱柜了怎么办 刮水泥浆的墙面刮不住腻子怎么办 小学二年级孩子偷钱 老师怎么办 发现自己读初中的儿子偷钱怎么办? 做错事了得不到亲人的原谅怎么办? 窗口 窗套与墙缝隙大怎么办 中班小孩还不会认1到10怎么办 母猫奶头被小猫咬伤了怎么办 口红不小心弄到衣服上怎么办 脖子后背疼的睡不着觉应该怎么办 君子兰用高锰酸钾泡浓度高了怎么办 五个月宝宝认人不要奶奶睡怎么办 幼儿小班安全卡鱼刺了怎么办教案 学籍在一年级学生在二年级怎么办 一岁多宝宝挑食不爱吃饭菜怎么办饭