归并排序(从上到下、从下到上)——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 ...
随机推荐
- HBase —— 集群环境搭建
一.集群规划 这里搭建一个3节点的HBase集群,其中三台主机上均为Regin Server.同时为了保证高可用,除了在hadoop001上部署主Master服务外,还在hadoop002上部署备用的 ...
- eclipse中junit简单使用
1.在工程中右击 Build Path,Add libraries 然后就可以运行对应的方法了,不需要main方法调用了
- nginx之gzip压缩
nginx的gizp压缩 为了使网站节省带宽和加快访问速度,在服务器方面的一个优化的就是使用nginx提供的gzip压缩. 一.使用压缩原理: 1.当用户使用浏览器访问网站时,就是在发送一个http请 ...
- 使用docker部署zabbix
1 官方地址 官方写的很详细并且是中文的,一步步按照操作就可以 https://www.zabbix.com/documentation/3.4/zh/manual/installation/cont ...
- python 基础学习笔记(1)
声明: 本人是在校学生,自学python,也是刚刚开始学习,写博客纯属为了让自己整理知识点和关键内容,当然也希望可以通过我都博客来提醒一些零基础学习python的人们.若有什么不对,请大家及时指出, ...
- Rstudio调用plot()函数时,出现错误的处理方法
按照书上的例子敲出代码后,发现Rstudio无法识别C盘user文件夹下的中文用户名.如下图所示: 按照网上的做法,尝试修改计算机user下的用户名,没修改成功. 另一种做法是在plot()函数前面加 ...
- 带你全面了解高级 Java 面试中需要掌握的 JVM 知识点
目录 JVM 内存划分与内存溢出异常 垃圾回收算法与收集器 虚拟机中的类加载机制 Java 内存模型与线程 虚拟机性能监控与故障处理工具 参考 带你全面了解高级 Java 面试中需要掌握的 JVM 知 ...
- python网络爬虫(11)近期电影票房或热度信息爬取
目标意义 为了理解动态网站中一些数据如何获取,做一个简单的分析. 说明 思路,原始代码来源于:https://book.douban.com/subject/27061630/. 构造-下载器 构造分 ...
- 解决thinkphp在开发环境下文件模块找不到的问题
win10系统下,phpstudy开发环境下小问题描述: 找不到public公共模块. Not Found The requested URL /public/admin/login.html was ...
- 基于webpack4+vue-cli3项目的换肤功能
起因 最近因公司需求,需要实现主题换肤功能,不仅仅是颜色的更改,还需要包括图片,字体等文件等更换,因此在百度里各种实现方案后,决定根据scss+style-loader/useable做换肤. 项目开 ...