归并排序

来源:互联网 发布:网络管理与维护 王平安 编辑:程序博客网 时间:2024/04/28 18:26

归并排序是一种外部存储设备最常用的排序方法。该方法是分治法典型应用。

归并排序一般分为2个步骤:

   step1.将排序数据分成若干份,然后使用适当的内部排序法进行排序,得到若干有序序列

    step2.将step1的有序序列归并为一个大的有序序列(通常是两两归并,所以又称二路归并),等到所有的序列都归并为一个序列后,就排序好了。

因此要解决2个问题:1.如何划分序列    2.如何进行归并操作


1.划分序列

(1)将序列从中间分成左子区间和右子区间

(2)将左子区间从中间分成左右2个子区间,再将2个子区间继续划分,直到子区间内的元素个数为1个或者2个

(3)同理,将右子区间从中间分成左右2个子区间,再将2个子区间继续划分,直到子区间内的元素个数为1个或者2个

从上面的步骤,我们会很自然的想到用递归来解决。

2.归并操作

(1)从左和右区间开始处,各取一个元素比较大小,较小的元素存入归并数组

(2)依次进行(1)的操作,直到有一个区间把元素取空为止,比如左区间的元素应经全部存入归并数组,而有区间还有3个元素(假设)没有存入归并数组,那么着3个元素肯定比左区间的所有数值都打。因此,把右区间剩下的3个元素全部存入归并区间。

(3)至此左右2个区间的归并操作完成

 

至此,2个问题解决了,那么该怎么将2个操作组合呢?

还是要遵循归并排序的2个步骤:

  1.首先,采用递归划分出左区间和右区间

   2.其次,对这两个区间进行归并操作

下面是代码:

#include <stdio.h>#define MAXSIZE100/*===================================*//*归并排序 *//*===================================*/int merge_array[MAXSIZE];//归并函数void merging(int *a,int low, int high){int i, j, k, S, Q, mid;i = low;//左半区下标k = 1;//merge_array归并数组下标mid = (low + high) / 2;j = mid + 1;//右半区下标while((i <= mid) && (j <= high)){//分别从左半区和右半区取一个数据,把较小的数据存入归并数组if(a[i] < a[j]){merge_array[k] = a[i];i++;}else{merge_array[k] =a[j]; j++;}k++;}//如果2个组中有一个结束,则把未结束组的其余元素全部送mergeif(i > mid)//左半区结束{S = j;//S存储接下来a数组能要顺序存入merge_array归并数组内的起始下标Q = high;//S存储接下来a数组能要顺序存入merge_array归并数组内的终止下标}else//右半区结束{S = i;Q = mid;}for(i=S; i<=Q; i++, k++)//从a[S]开始,把未结束的区间内剩余元素依次存入merge_array内merge_array[k] = a[i];for(i=low, j=1; i<=high; i++, j++)//把归并数组内的数据按照对应的下标复制到原来数组aa[i] = merge_array[j];}//归并排序void merge_sort(int *a, int low, int high){int mid;if(low == high)//low==high,即区间内元素个数为1或2时,结束递归return;mid = (low + high) / 2;//以中点分割区间merge_sort(a, low, mid);//左半区间递归merge_sort(a, mid+1, high);//右半区间递归merging(a, low, high);//对左右2个区间进行归并操作}/*===================================*//*主函数 *//*===================================*/int main(){int i;int data[MAXSIZE] = {0, 3, 7, 10, 9, 1, 8, 6, 5, 2, 4, 12, 11};merge_sort(data, 1, 12);for(i=1; i<13; i++){printf("%d ", data[i]);}}
                                             
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁宝宝对牛奶鸡蛋过敏了怎么办 两岁宝宝坐不住好跑怎么办 宝宝两岁多了不愿意坐小马桶怎么办 坐火车小孩拉屎在被子上怎么办 川航飞机票名字错了一个字怎么办 胜战本领怎么看走向战场怎么办 数数字油画你的颜料干了怎么办? 数字油画涂颜料涂错了怎么办 绝地求生模拟器注册已达上限怎么办 孕妇把番茄和虾一起吃了怎么办 4岁宝贝吃了玩具小电池怎么办 微信使用零钱需完善实名信息怎么办 两岁宝宝刷牙不会吐水怎么办 孩子牙龈上长了小牙怎么办 供暖公司未供暖却收取供暖费怎么办 两岁宝宝认知和语言能力低怎么办 蜡笔同步被对方发现删掉的怎么办 微信时间和手机时间不同步怎么办 孩子们家乡爱画美丽的也自己怎么办 娃把豆豆弄进鼻孔了怎么办 20岁了不知道自己该干什么怎么办 遇到一个新手买家恶意拍下怎么办 淘宝卖螃蟹有什么要求美工怎么办 淘宝衣服吊牌剪了想退货怎么办修 用图片在淘宝搜衣服搜不到怎么办 汽车黑塑料水砂纸磨的不平怎么办 sat报名要你填10位电话怎么办 手绘板连接电脑绘画有点迟钝怎么办 走路不小心滑了一下特尴尬怎么办 小孩子头撞了头发长不出来怎么办 小孩子头磕破了不长头发怎么办 晚上洗了冷水头早上头痛怎么办 头发洗了一天就油了怎么办 米诺地尔搽剂喷了头皮油怎么办 头发可以种植吗如果是秃顶怎么办 前额头发少怎么办如何使头发增多 头发又细又软又少怎么办 宝宝一岁了头发又少又黄怎么办 生完孩子头发掉的厉害怎么办 洗完头发后头发很蓬松怎么办 头发掉的厉害怎么办吃什么好得快