归并排序(从上到下、从下到上)——C语言
归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之),将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为二路归并
1、归并排序的基本思想
将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列
2、归并排序的算法描述
(1)“分解”——将序列每次折半划分(递归实现)
(2)“合并”——将划分后的序列段两两合并后排序
如何合并?
在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。
这两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]。
先将他们合并到一个局部的暂存数组R2中,带合并完成后再将R2复制回R中。
我们称 R[low, mid] 第一段,R[mid+1, high] 为第二段。
每次从两个段中取出一个记录进行关键字的比较,将较小者放入R2中,最后将各段中余下的部分直接复制到R2中。
经过这样的过程,R2已经是一个有序的序列,再将其复制回R中,一次合并排序就完成了。
/* 将序列对半拆分直到序列长度为1*/
void MergeSort_UptoDown(int *num, int start, int end)
{
int mid = start + (end - start) / ; if (start >= end)
{
return;
} MergeSort_UptoDown(num, start, mid);
MergeSort_UptoDown(num, mid + , end); Merge(num, start, mid, end);
} void Merge(int *num, int start, int mid, int end)
{
int *temp = (int *)malloc((end-start+) * sizeof(int)); //申请空间来存放两个有序区归并后的临时区域
int i = start;
int j = mid + ;
int k = ; while (i <= mid && j <= end)
{
if (num[i] <= num[j])
{
temp[k++] = num[i++];
}
else
{
temp[k++] = num[j++];
}
} while (i <= mid)
{
temp[k++] = num[i++];
}
while (j <= end)
{
temp[k++] = num[j++];
} //将临时区域中排序后的元素,整合到原数组中
for (i = ; i < k; i++)
{
num[start + i] = temp[i];
} free(temp);
}
(图片来源:https://www.cnblogs.com/chengxiao/p/6194356.html)
完整代码:
#include <stdio.h>
#include <stdlib.h> void MergeSort_UptoDown(int *num, int start, int end);
void Merge(int *num, int start, int mid, int end); int main()
{
/* 归并排序(升序) */
int num[] = {, , , , , , , , , };
int length = sizeof(num) / sizeof(num[]);
int i; MergeSort_UptoDown(num, , length - ); for (i = ; i < length; i++)
{
printf("%d ", num[i]);
} return ;
} /* 将序列对半拆分直到序列长度为1*/
void MergeSort_UptoDown(int *num, int start, int end)
{
int mid = start + (end - start) / ; if (start >= end)
{
return;
} MergeSort_UptoDown(num, start, mid);
MergeSort_UptoDown(num, mid + , end); Merge(num, start, mid, end);
} void Merge(int *num, int start, int mid, int end)
{
int *temp = (int *)malloc((end-start+) * sizeof(int)); //申请空间来存放两个有序区归并后的临时区域
int i = start;
int j = mid + ;
int k = ; while (i <= mid && j <= end)
{
if (num[i] <= num[j])
{
temp[k++] = num[i++];
}
else
{
temp[k++] = num[j++];
}
} while (i <= mid)
{
temp[k++] = num[i++];
}
while (j <= end)
{
temp[k++] = num[j++];
} //将临时区域中排序后的元素,整合到原数组中
for (i = ; i < k; i++)
{
num[start + i] = temp[i];
} free(temp);
}
归并排序(从上到下、从下到上)——C语言的更多相关文章
- react + iscroll5 实现完美 下拉刷新,上拉加载
经过几天的反复折腾,总算做出一个体验还不错的列表页了,主要支持了下拉刷新,上拉加载两个功能. 一开始直接采用了react-iscroll插件,它是基于iscroll插件开发的组件.但是开发过程中,发现 ...
- 在SpringMVC框架下实现文件的 上传和 下载
在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...
- 原生JS实现分页效果2.0(新增了上一页和下一页,添加当前元素样式)
虽然写的很烂,但至少全部都是自己写的,因为这个没有固定的顺序,所以就没有封装,如果你技术好的话,可以你写的分享给我,谢谢. <!DOCTYPE html><html lang=&qu ...
- iOS MJRefresh下拉刷新(上拉加载)使用详解
下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...
- js获取上一个月、下一个月格式为yyyy-mm-dd的日期
/** * 获取上一个月 * * @date 格式为yyyy-mm-dd的日期,如:2014-01-25 */ function getPreMonth(date) { var arr = date. ...
- PHP实现上一篇、下一篇
//php实现上一篇.下一篇 获取当前浏览文章id $id = isset($_GET[ ? intval($_GET['id']) : ""; 下一篇文章 $query = my ...
- SVPullToRefresh 下拉刷新,上拉加载
https://github.com/Sephiroth87/ODRefreshControl 类似刷新控件,类似qq动画的那种刷新. 一.下载第三方库 https://github.com/samv ...
- Android PullToRefreshListView上拉刷新和下拉刷新
PullToRefreshListView实现上拉和下拉刷新有两个步骤: 1.设置刷新方式 pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH) ...
- c++(vs上)与g++(linux下)对于++操作的汇编代码解读
先来看一个代码,估计很多同学都碰到过其中的某一个. #include <stdio.h> #include <iostream> using namespace std; in ...
- ListView(2)最简单的上拉刷新,下拉刷新
最简单的上拉刷新和下拉刷新,当listview滚动到底部时向上拉刷新数据.当listview滚动到最顶部时下拉刷新. 图1,上拉刷新 图2,下拉刷新 1,设置lisview,加载heade ...
随机推荐
- ASP.NET MVC/Core表单提交后台模型二级属性验证问题
起因 这个是网友在官网论坛的提问:https://fineui.com/bbs/forum.php?mod=viewthread&tid=22237 重新问题 本着务实求真的态度,我们先来复现 ...
- 并发编程-concurrent指南-阻塞队列-优先级的阻塞队列PriorityBlockingQueue
PriorityBlockingQueue是一个支持优先级的无界阻塞队列. 它使用了和类 java.util.PriorityQueue 一样的排序规则.你无法向这个队列中插入 null 值. 所有插 ...
- 充气娃娃什么感觉?Python告诉你
上期为大家介绍了requests库的基本信息以及使用requests库爬取某东的商品页,收到了很多同学的反馈说期待猪哥的更新,猪哥感到非常开心,今天就带大家来玩一把刺激的! 一.需求背景 在实际开发过 ...
- 获取浏览器ip地址
<script src="http://lib.sinaapp.com/js/jquery/1.8.3/jquery.min.js"></script> & ...
- 我的那些年(12)~公司技术转行,我也跟着转到java了
回到目录 我的那些年(12)~公司技术转行,我也跟着转到java了 CTO换人了 微软技术栈不被认可经常被喷 技术统一向java转 换了mac book后,docker还是很占内存 学习springb ...
- scrapy基础知识之 关于爬虫部分一些建议:
1.尽量减少请求次数,能抓列表页就不抓详情页,减轻服务器压力,程序员都是混口饭吃不容易. 2.不要只看 Web 网站,还有手机 App 和 H5,这样的反爬虫措施一般比较少. 3.实际应用时候,一般防 ...
- 【深入浅出-JVM】(3):浮点数
-5 浮点数推导 二进制转十进制 1 10000001 01000000000000000000000 1 10000001 101000000000000000000000 如果指数位不全为 0 则 ...
- shell_chmod与目录权限
此篇文档将讲解关于linux中文件权限常用命令chmod.为了达到一个比较好的效果,我会在需要的地方实际上机验证测试,并截图给朋友们看.我的linux机器装的是(opensuse-11.3),并且以文 ...
- 码云及Git的使用
什么是码云 码云就是相当一个远程仓库,在以后的工作中,你和同事负责工作的不同部分,齐头并进,最后上传到码云,类似于一个汇总的作用. 同一个绳上的不同分支 码云网址链接:https://gitee.co ...
- 基于TCP协议的套接字编程
06.26自我总结 1.关于Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在 ...