排序算法8----归并排序(非递归)(C)

news2025/1/11 20:38:06

       1、介绍

        归并排序既可以是内排序(在内存上的数据排序),也可以是外排序(磁盘上)(硬盘)(在文件中的数据排序)。

        其他排序一般都是内排序。

        区别于快速排序的非递归,归并排序非递归不适合使用栈。

        因为快速排序的本质是一种前序递归,而归并排序的本质是一种后序递归,并没有“根”来区分左右。

        那么归并排序的非递归应该怎么样实现呢?

        2、思想

        我们先想想归并的思想和目的:递归的分治是将数组分割成两边有序的子序列,然后再合并这两个。那么我们是否可以直接将数组中两两元素归并呢?答案是:对的!因为我们将数组中所有元素看作两两一组(每组数据中都各有一个元素),那么这一组中的两个元素单个来看就是有序的子序列,然后合并这两个元素。再往上就是四四一组(每组数据中都各有两个有序的元素),八八一组........37d6c6e9443a437cb6846fbf4345fcf2.png

        听起来好像很简单,其实坑很多,下面慢慢实现。

        3、代码

void MergeSortNonR_incline(int* arr, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail\n");
		exit(-1);
	}

	int gap = 1;//1-1归
	//gap代表归并每组数组个数,即gap个和gap个归并
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)//[0,n)
		{
			int begin1 = i, end1 = i + gap - 1;//第一组
			int begin2 = i + gap, end2 = i + 2 * gap - 1;//第二组
			//[begin1,end1],[begin2,end2] 归并
			//[0,0]-[1,1]归,[2,2]-[3,3],[4,4]-[5,5]....
			//[0,1]-[2,3]归, [4,5]-[6,7]....
			//[0,3]-[4,7]归, [8,11]-[11,15]......
			// ......
			//注意:begin1不会越界,end1,begin2,end2都可能越界,所以要修正
			if (end1 >= n || begin2>=n)
				break;
			if (end2 >= n)
				end2 = n - 1;

			//合并,将arr中对应位置,放入tmp的对应位置
			int j = begin1;
			while (begin1 <= end1 && begin2 <= end2)
			{

				if (arr[begin1] < arr[begin2])
					tmp[j++] = arr[begin1++];
				else
					tmp[j++] = arr[begin2++];
			}


			while (begin1 <= end1)
			{
				tmp[j++] = arr[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[j++] = arr[begin2++];
			}

			//[begin1,end1],[begin2,end2]
			memcpy(arr + i, tmp + i, sizeof(int) * (end2-i+1));//每次归并完拷贝回去
		}
		gap *= 2;
	}

	free(tmp);
	tmp = NULL;
}

        4、实现效果

	int arr[] = { 1,6,41,32,5,12,7,11 };
	int size = sizeof(arr) / sizeof(int);
	printf("原数组\n");
	for (int i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	printf("排序后\n");
	MergeSortNonR_incline(arr, size);
	for (int i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

原数组:1 6 41 32 5 12 7 11

排序后:1 5 6 7 11 12 32 41

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

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

相关文章

uni-app的学习【第三节】

五 运行环境判断与跨端兼容 uniapp为开发者提供了一系列基础组件,类似HTML里的基础标签元素,但uni-app的组件与HTML不同,而是与小程序相同,更适合手机端使用。 虽然不推荐使用 HTML 标签,但实际上如果开发者写了`div`等标签,在编译到非H5平台时也会被编译器转换为 `view`…

爬虫-8-数据存储-mysql

#mysql占空间最小吧&#xff0c;数据存储没问题吧 (//∇//)

Flowable:BpmnModel API

之前都是使用工具在绘制流程图&#xff0c;但是还是很少去认真的去看这个xml&#xff0c;有时候我们要从xml中分析获取一些结果&#xff0c;这个时候就要对xml及对应的api有足够的认识。 一&#xff1a;重新认识bpmn definitions&#xff1a;根节点用于定义流程。 bpmndi:BPMND…

台式OLED透明屏的6大基本要素

台式 OLED 透明屏作为一种创新的显示技术&#xff0c;正逐渐走进人们的视野。本文将为您全面介绍台式 OLED 透明屏的各个方面&#xff0c;包括类别、尺寸、技术参数原理、应用、主要厂家&#xff08;尼伽&#xff09;以及价格因素。 一、类别台式 OLED 透明屏根据不同的需求和应…

Java 实现双链表

文章目录 双链表&#xff08;Doubly Linked List&#xff09;是一种常用的数据结构&#xff0c;它与单链表相似&#xff0c;但每个节点除了包含指向下一个节点的指针外&#xff0c;还包含一个指向前一个节点的指针。 双链表的节点由三部分组成&#xff1a;数据域&#xff08;存…

帆软报表11.0.19增加postgres数据源方案

项目使用postgres数据库&#xff0c;帆软报表集成开发时需要手工增加该数据源。 https://help.fanruan.com/finereport/doc-view-2563.html 但增加数据源后测试报告无此驱动&#xff0c;经查看文档&#xff0c;现在是通过驱动管理来上传&#xff0c; 但新版又不允许上传驱动JAR…

威尔·库尔特《趣学贝叶斯统计:橡皮鸭、乐高和星球大战中的统计学》学习笔记(1):以A/B测试为例学习贝叶斯统计

主要是新学期的概率论的作业要求&#xff1a;Write a summary (no more than of a page) of your experience with an application of probability to a real-life situation (e.g., an engineering problem. –How was probability used to model the phenomena/situation?…

力扣刷题(无重复字符的最长子串)

3. 无重复字符的最长子串https://leetcode.cn/problems/longest-substring-without-repeating-characters/ 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是…

【Emgu.CV教程】5.3、几何变换之金字塔变换

这一段文字描述来自百度百科&#xff1a; 图像金字塔是图像多尺度表达的一种&#xff0c;是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的图像金字塔是一系列以金字塔形状&#xff08;自下而上&#xff09;逐步降低&#xff0c;且来源于同一张原始图的图像分辨率…

6、CLIP:连接文本和视觉世界的预训练模型

目录 一、论文题目 二、背景与动机 三、创新与卖点 四、技术细节 模型结构 简易代码 clip实现zero shot分类 五、为什么是CLIP?为什么是对比学习&#xff1f; 六、一些资料 在人工智能领域&#xff0c;文本和图像是两个极其重要的数据形式。传统上&#xff0c;机器学…

python 集合的详细用法

当前版本&#xff1a; Python 3.8.4 简介 Python中的集合是一种无序、可哈希的且不重复的数据类型&#xff0c;用于存储唯一的元素。集合的实现基于哈希表&#xff0c;因此在插入、查找和删除元素时具有高效性能。集合的每个元素都必须是不可变的&#xff0c;可以是数字、字符…

阿里AnyText:多语种图像文字嵌入的突破

模型简介 随着Midjourney、Stable Difusion等产品的兴起&#xff0c;文生图像技术迅速发展。然而&#xff0c;在图像中生成或嵌入精准文本一直是一个挑战&#xff0c;尤其是对中文的支持。阿里巴巴的研究人员开发了AnyText&#xff0c;这是一个多语言视觉文字生成与编辑模型&a…

SpringBoot 全局异常统一处理:BindException(绑定异常)

概述 在Spring Boot应用中&#xff0c;数据绑定是一个至关重要的环节&#xff0c;它负责将HTTP请求中的参数映射到控制器方法的入参对象上。在这个过程中如果遇到任何问题&#xff0c;如参数缺失、类型不匹配或验证失败等&#xff0c;Spring MVC将会抛出一个org.springframewo…

安达发|APS工序排程甘特图功能介绍

工序排程甘特图的主要功能 1. 显示工序时间安排&#xff1a;工序排程甘特图可以清晰地展示生产过程中各个工序的开始时间、结束时间和持续时间&#xff0c;从而帮助企业了解生产过程中各个环节的时间安排。 2. 显示工序进度情况&#xff1a;通过工序排程甘特图&#xff0c;企业…

通过myBatis将sql语句返回的值自动包装成一个java对象(3)

1.如果sql字段和java字段名字不一样怎么办&#xff1f; 之前我们将sql返回值转换为java对象时&#xff0c;每条sql的返回值的字段名和java类中的字段名是一一对应的&#xff0c;ie&#xff1a;sql选择的user有username和password两个字段&#xff0c;java中的user对象也有两个…

开源项目CuteSqlite开发笔记(七):CuteSqlite释放BETA版本啦

经过大半年的开发&#xff0c;CuteSqlite程序代码不知不觉来到了6万行&#xff0c;有效行数4万行&#xff0c;CuteSqlite开发完成了一个小版本&#xff0c;进入下一个阶段&#xff0c;并于2024元旦释放BETA版本&#xff0c;有兴趣的朋友可以下载试用。 GitHub下载https://gith…

Linux系统下编译MPlayer

一、编译MPlayer 在 http://www.mplayerhq.hu/design7/dload.html 下载MPlayer源码 执行命令&#xff1a; tar -xf MPlayer-1.5.tar.xz cd MPlayer-1.5 ./configure --prefix$(pwd)/install --yasm make make install 然后在install/bin目录下即会生成mplayer的可执行文件 二…

基于Java+SSM的技术的社区人口管理系统详细设计和实现【附源码】

基于JavaSSM的技术的社区人口管理系统详细设计和实现 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 …

elasticsearch[一]-索引库操作(轻松创建)、文档增删改查、批量写入(效率倍增)

elasticsearch[一]-索引库操作(轻松创建)、文档增删改查、批量写入(效率倍增) 1、初始化 RestClient 在 elasticsearch 提供的 API 中&#xff0c;与 elasticsearch 一切交互都封装在一个名为 RestHighLevelClient 的类中&#xff0c;必须先完成这个对象的初始化&#xff0c;…

Vue知识总结-下

VUE-组件间通信 组件的自定义事件 概述&#xff1a;是一种组件间通信的方式,适用于&#xff1a;子组件>父组件使用场景&#xff1a;A是父组件,B是子组件,B给A传递数据,那么需要在A组件中绑定自定义事件(事件的回调也在A中)使用步骤 绑定自定义事件&#xff1a; 第一种方式…