归并排序(C语言)

news2024/11/25 2:22:48

目录

1.归并排序图解

2.归并排序(递归版)

3.归并排序(非递归版)


1.归并排序图解

归并排序的核心思想是让左右两边有序的部分进行合并比较排序,具体什么意思呢?分两点:

1.分:左右两边要有序,如何做到左右两边有序呢?看上面的图,当我们将一个数组进行分离,一直分,知道左右两边进行对比的数只有一个,这种情况下肯定有序。

2.治:这个过程就是将左右两边数进行排序,然后排好后再进行重复操作,就将整个数组置为有序了。

我们用代码来加深整个过程的理解。

2.归并排序(递归版)

我们先来讲这个递归版本的代码思想:

我这里传的四个参数分别是:a--数组,begin--头下标,end--尾下标,tmp用来拷贝的数组。

从图中我们不难发现分的过程是一个除以2倍的关系,所以我们用mid来记录接下来递归的左边尾下标和右边头下标,递归终止条件就是头下标大于等于尾下标的时候,接下来我们进行的操作就是定义一下左边的头尾下标和右边的头尾下标,还有一个i用作tmp的下标,接下来就开始比对了,我们进行升序排序,所以我们把小的往tmp里放,循环的结束条件就是左右两边随便一边走完就停止,接下来再把没输完的全部输进去就好,不要忘记我们的tmp充当的是临时拷贝的角色,我们要改动的是数组a,所以我们使用库函数memcpy来将tmp里的数拷贝到a中,这样就模拟了治的过程,也就是说每一趟递归我们a里的值跟上面图片治部分的每一行是一样的。

我们来看看结果:

归并是一种时间复杂度为O(NlogN)的排序算法,而且它的稳定性也比较高。

我们再来感受一下不用递归,归并怎么来写。

3.归并排序(非递归版)

//归并排序 非递归实现
void MergeSortNrec(int* a, int begin, int end, int* tmp)
{
	int gap = 1;
	while (gap < end+1)
	{
		for (int i = 0; i < (end - begin + 1); i += 2*gap)
		{
			int begin1 = i, end1 = i + gap-1;
			int begin2 = i + gap, end2 = i + gap * 2-1;
			int j = begin1;
			if (end1 >= end+1|| begin2 >= end+1)
			{
				break;
			}
			if (end2 >= end+1)
			{
				end2 = end;
			}
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] <= a[begin2])
				{
					tmp[j++] = a[begin1++];
				}
				else
				{
					tmp[j++] = a[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[j++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[j++] = a[begin2++];
			}
			memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));
		}
	    gap *= 2;
	}
}

非递归版我们采用的逻辑还是一样的,只不过实现形式有很大区别,递归中我们是分治,用递归达到分的目的,这里我们没有递归,怎么办呢,我们可以用循环来实现,这里我就不卖关子了,我们的总体思路是直接到分的最后一步,也就是一个跟一个比的情款,然后再往回去走。

所以,上面代码中的gap的作用就是控制对比元素的个数,一开始一个跟一个对比,每一趟新的循环gap阔两倍,然后治的过程,代码跟我们递归版的是相差无几的,但是这里的end1,begin2,end2要注意有可能会发生越界的情况,所以我们要对他们进行判断,当end1和begin2中的任意一个出现越界情况的话,我们就终止循环,因为光是左边的就已经到尾了,就没必要比右边了(右边压根没数据了);如果是end2越界,说明这个数组长度不是gap的整数倍了,我们就将end2重置为尾下标就行了,保证了不会出现越界的行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1393869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SwitchyOmega插件管理海外動態IP代理設置教程

SwitchyOmega插件很好解決了管理多個代理並在它們之間切換的問題&#xff0c;通過本文來全面瞭解SwitchyOmega&#xff0c;比如SwitchyOmega插件的用途、它的主要功能和應用、怎麼下載和使用&#xff0c;如何管理海外動態IP代理。 SwitchyOmega插件有什麼用途&#xff1f; Swit…

扫描电子显微镜在材料失效分析中的主要作用

扫描电子显微镜&#xff08;Scanning Electron Microscope&#xff0c;简称SEM&#xff09;是一种高分辨率的显微镜&#xff0c;能够在纳米级别上观察样品的表面形貌和微观结构。在材料失效分析中&#xff0c;SEM起着至关重要的作用&#xff0c;为深入理解材料的性质和失效机制…

excel统计分析——Scheffe法多重比较

参考资料&#xff1a;生物统计学 Scheffe法&#xff08;雪费法&#xff09;多重比较和LSD法一致&#xff0c;但通过k-1作为F分布的第一自由度对临界值进行调整&#xff1a; 其中&#xff0c;k为处理水平数&#xff0c;df为误差自由度&#xff1b;为 excel操作步骤如下&#xf…

ADSelfService Plus 推出离线多因素身份验证以提升远程工作安全性

采用先进验证方法&#xff0c;确保在任何时间、地点或连接问题下对业务数据的合法访问即使远程用户未连接到身份验证服务器或互联网&#xff0c;也可通过MFA安全认证。 MFA 得克萨斯州德尔瓦雷 — 2023年5月3日 — Zoho Corporation 旗下的企业IT管理部门ManageEngine今日宣布…

rust让你的python飞起来!

Note: 本文作为入门教程&#xff0c;抛砖引玉&#xff0c;帮你初步了解如何使用rust为python写扩展模块&#xff0c;涉及从头到尾的详细步骤&#xff0c;基于此&#xff0c;剩下的只有深入rust&#xff0c;才能做得更好。 众所周知&#xff0c;python性能比较差&#xff0c;尤其…

自动驾驶轨迹规划之碰撞检测(三)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.基于圆覆盖 2.BVH 3.MATLAB自动驾驶工具箱 4 ROS内置的模型 自动驾驶轨迹规划之碰撞检测&#xff08;一&#xff09;-CSDN博客 自动驾…

性价比高的宠物空气净化器有哪些?五款猫用空气净化器测评推荐!

作为一位经验丰富的铲屎官&#xff0c;我深切理解养猫后家里到处都是猫毛和异味的困扰。养猫后&#xff0c;家里的空气质量往往变得不佳&#xff0c;猫毛和皮屑漫天飞舞。而如今&#xff0c;室内空气质量普遍较差&#xff0c;受到雾霾、螨虫和甲醛等污染。长期处于低质量的室内…

postman测试文件上传接口设置说明

Postman介绍及下载链接地址 Download Postman | Get Started for Free 打开postman 选择POST方法&#xff0c;然后设置goform 设置Header参数 设置Body参数&#xff0c;选择数据form-data 添加文件&#xff0c; 选择为文件属性 添加需要上传的文件

【备战蓝桥杯】吃奶酪问题 / 超硬核,文附template拓展知识!

蓝桥杯备赛 | 洛谷做题打卡day9 文章目录 蓝桥杯备赛 | 洛谷做题打卡day9再来了解一下状压dp**简介(Introduction)****描述(Description)** - 吃奶酪题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示数据规模与约定提示 * template拓展知识我的一些话 【引入】今天…

sftp配置互信:sftp免密登录

一、安装ssh 使用yum命令安装或者去ssh官网下载进行安装 yum install openssh.x86_64二、设置免密 在asd(192.168.47.130)通过ssh或者sftp登录demo(192.168.47.140) shh免密登录有俩种方式 1、生成ssh公钥以及私钥 俩台服务器都不要生成 ssh-keygen在asd执行 在demo执行 …

探索直流电源模块的应用领域

探索直流电源模块的应用领域 直流电源模块广泛应用于许多领域&#xff0c;包括电子设备、通信、工业自动化、航空航天等。以下是一些常见的应用领域&#xff1a; 1. 电子设备&#xff1a;直流电源模块用于给各种电子设备供电&#xff0c;如计算机、手机、平板电脑、摄像机等。…

从零实现一套低代码(保姆级教程)【后端服务】 --- 【18】实现页面接口对应的前端

摘要 在上一篇中&#xff0c;我们已经把和页面相关的接口完成的差不多了。从创建页面&#xff0c;更新页面等等&#xff1a; 有了接口之后&#xff0c;我们就可以构建前端页面了。那这部分前端内容我们应该写在哪里呢&#xff1f; 有两种方式&#xff1a; 直接写在我们的Xin…

canvas绘制不同样式的五角星(图文示例)

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

十三、Qt 操作PDF文件放大缩小

一、在《十、Qt 操作PDF文件-CSDN博客》中我们用Poppler类库打开了PDF文件&#xff0c;在《十二、Qt 操作PDF文件(2)-CSDN博客》介绍了通过按钮进行上一页、下一页、跳转到某一页等功能&#xff0c;在本章节中&#xff0c;加入了 通过鼠标滚轮可以翻页。通过按住Ctrl鼠标滚轮可…

【十进制与二进制如何转换?推荐一个超好用的公式编辑器】

在计算机科学和电子工程中&#xff0c;二进制是一种非常重要的数字系统&#xff0c;因为它在数字处理和数据传输中被广泛使用。因此&#xff0c;理解如何将十进制数转换为二进制数是非常重要的。 可以使这个计算过程更加简单和快速。而且还可以用于其他数学方程式的编写和编辑。…

香港服务器带宽大点的(香港大带宽推荐)

在当今数字化时代&#xff0c;服务器带宽成为了企业发展的重要基石。对于需要处理大量数据和流量的企业来说&#xff0c;选择一款带宽充足、性能稳定的服务器是至关重要的。香港作为全球互联网的中心之一&#xff0c;其服务器带宽质量备受关注。本文将为您推荐几款香港大带宽服…

MySQL下对[库]的操作

目录 创建数据库 创建一个数据库案例&#xff1a; 字符集和校验规则&#xff1a; 默认字符集&#xff1a; 默认校验规则&#xff1a; 查看数据库支持的字符集&#xff1a; 查看数据库支持的字符集校验规则&#xff1a; 校验规则对数据库的影响&#xff1a; 操作数据…

黑马程序员JS基础笔记

js基础 软件第一天第二天 第三天第四天第五天 软件 截图软件snipaste esc取消 f1后再f1可取色&#xff0c;shift可换十六进制&#xff0c;c复制 画笔软件 思维导图软件 笔记软件 vscode报错插件Error Lens 第一天 组成&#xff1a;ECMAScriptWeb APIs(DOMBOM) 权威网站…

Tensorflow2.0笔记 - 基础数学运算

本笔记主要记录基于元素操作的,-,*,/,//,%,**,log,exp等运算&#xff0c;矩阵乘法运算&#xff0c;多维tensor乘法相关运算 import tensorflow as tf import numpy as nptf.__version__#element-wise运算&#xff0c;对应元素的,-,*,/,**,//,% tensor1 tf.fill([3,3], 4) ten…

前端面试题-CSS3新增特性

增加了transition过渡和animation动画 transition过渡,可以实现元素状态的渐变效果&#xff0c;即当元素的状态发生变化时&#xff0c;元素会平滑的过渡到新的状态。要使用transition属性&#xff0c;需要指定要执行过渡效果的属性&#xff0c;过渡效果的持续时间&#xff0c;…