数据结构排序——详细讲解归并排序(c语言实现递归及非递归)

上次是快排和冒泡:数据结构排序——详解快排及其优化和冒泡排序(c语言实现、附有图片与动图示意)

今天为大家带来归并排序


文章目录

  • 1.基本思想
  • 2.递归实现
  • 3.非递归实现


1.基本思想

归并排序是一种分治算法,它将序列分成两个子序列,分别对子序列进行排序,然后将排序好的子序列合并起来。这个过程可以递归地进行,直到序列长度小于等于1时停止递归。

在合并子序列的过程中,需要比较两个子序列的元素,并按顺序将它们合并成一个有序序列

注意:归并排序的关键在于合并两个有序的子序列,这一步需要额外的空间来存储中间结果。在实际的实现中,可以使用递归非递归的方式来完成归并排序

请添加图片描述


2.递归实现

递归归并排序:

  1. 如果序列长度小于等于1,无需排序,直接返回
  2. 将序列分成两个子序列,分别进行递归归并排序
  3. 合并两个已排序的子序列
void _MergeSort(int* a, int* tmp, int left, int right)//是下标,不是值
{
	if (left >= right)//只有一个元素或不存在这样的区间递归停止
	{
		return;
	}
	int mid = (left + right) / 2;//分成两部分,分别有序后再进行归并
	// [begin, mid][mid+1, end]
	_MergeSort(a, tmp, left, mid);
	_MergeSort(a, tmp, mid+1,right );//这两部分都有序啦
	//开始归并:归并到到tmp数组的相同位置,再拷贝回去

	int left1 = left; int right1 = mid;//第一个数组的两端
	int left2 = mid+1; int right2 = right;//第二个数组的两端
	int index = left;//两个数组是从left开始的,left给index就是到相同区间上

	while (left1 <= right1 && left2 <= right2)//两个比,小的放进去
	{
		if (a[left1] < a[left2])
		{
			tmp[index] = a[left1];
			index++;
			left1++;
		}
		else
		{
			tmp[index] = a[left2];
			index++;
			left2++;
		}
	}//有一个排完了,剩下的一个就直接放
	while (left1 <= right1)
	{
		tmp[index] = a[left1];
		index++;
		left1++;
	}
	while (left2 <= right2)
	{
		tmp[index] = a[left2];
		index++;
		left2++;
	}//到此,tmp内已经归并成功,接下来复制回a中
	memcpy(a + left, tmp + left, sizeof(int) * (right - left + 1));
}

void MergeSort(int* a, int n)
{
	//创建一个临时数组
	int tmp = (int*)malloc(sizeof(int) * n);
	assert(tmp);
	_MergeSort(a, tmp, 0, n - 1);//子函数,在这里递归不好,有动态开辟
	free(tmp);
}

int main()
{
	int a[] = { 10,6,7,1,3,9,4,2 };
	//MergeSortNonR(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));//用来打印数组的
	MergeSort(a, sizeof(a) / sizeof(int));
	PrintArray(a, sizeof(a) / sizeof(int));
	return 0;
}

请添加图片描述


3.非递归实现

非递归实现归并排序是一种迭代式的排序算法,它避免了递归调用带来的额外开销,通常使用循环和迭代来实现归并排序的过程:

  1. 确定归并区间的思路:对于给定的数组,首先将相邻的元素两两归并(gap=1),然后将归并的区间长度不断扩大,依次归并相邻的区间、长度为 2 的区间、长度为 4 的区间,直到整个数组都归并完成(gap=2)。*
  2. 归并的逻辑:在每次归并的过程中,根据当前的区间长度,确定待归并的两个区间的边界。然后比较这两个区间的元素,并将较小的元素依次放入临时数组中。当某一个区间的元素已经全部放入临时数组后,将另一个区间剩余的元素直接放入临时数组中。
  3. 复制回原数组:在每次归并完成后,将临时数组中归并好的结果复制回原数组中,以便进行下一轮的归并操作。
  4. 不断扩大归并区间:通过不断扩大归并的区间长度,最终完成整个序列的排序
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	assert(tmp);
	int gap = 1;//第一次1为长度
	while (gap < n)
	{
		for (int i = 0; i < n ; i += 2*gap)//每次两个区间的左起点都是i ,每次跳过两个gap
		{
			//一个区间里有gap个元素
			int left1 = i; int right1 = i + gap - 1;//第一个区间
			int left2 = i+gap; int right2 = i + 2*gap - 1;//第二个
			
			if (left2 > n)//没有与之相归并的第二个数组
			{
				break;//直接出去,进行下一层
			}
			if (right2 > n)
			{
				right2 = n - 1;
			}

			//开始归并
			int index = i;
			while (left1 <= right1 && left2 <= right2)//两个比,小的放进去
			{
				if (a[left1] < a[left2])
				{
					tmp[index] = a[left1];
					index++;
					left1++;
				}
				else
				{
					tmp[index] = a[left2];
					index++;
					left2++;
				}
			}//有一个排完了,剩下的一个就直接放
			while (left1 <= right1)
			{
				tmp[index] = a[left1];
				index++;
				left1++;
			}
			while (left2 <= right2)
			{
				tmp[index] = a[left2];
				index++;
				left2++;
			}//到此,tmp内已经归并成功,接下来复制回a中
			memcpy(a + i, tmp + i, sizeof(int) * (right2 - i + 1));
		}
		gap *= 2;
	}
}

请添加图片描述


今天就先讲这么多了,数据结构排序部分也马上迎来了尾声,感谢大家支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java多线程并发篇----第十篇

系列文章目录 文章目录 系列文章目录前言一、start 与 run 区别二、JAVA 后台线程三、什么是乐观锁前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、start 与 r…

【金猿人物展】DataPipelineCEO陈诚:赋能数据应用,发挥未来生产力

‍ 陈诚 本文由DataPipelineCEO陈诚撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度趋势人物榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 我们处在一个“见证奇迹”的时代。在过去的20年间&#xff0c;我们见证了大数据技术快速发展所带…

Flask+ Dependency-injecter+pytest 写测试类

最近在使用这几个在做项目&#xff0c;因为第一次用这个&#xff0c;所以不免有些问题。总结下踩的坑 1.测试类位置 首先测试类约定会放在tests里面&#xff0c;不然有可能发生引入包的问题&#xff0c;会报错某些包找不到。 2. 测试类依赖注入 这里我就用的真实的数据库操作…

Vue-17、Vue人员列表过滤(案例)

1、watch实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>列表渲染过滤</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js&qu…

C1-3.4 多个样本的向量化

C1-3.4 多个样本的向量化 1、为什么要用样本的向量化呢&#xff1f; 总结一句话&#xff1a;计算方便 下图是神经网络计算的步骤&#xff0c;右侧 是有一个输入变量a[0]&#xff08;什么是X呢&#xff0c;因为输入层有三个神经元&#xff0c;说明有三个输入变量&#xff0c;…

信号量机制

1965年&#xff0c;由荷兰学者迪科斯彻Dijkstra提出&#xff08;P、V分别代表荷兰语的Proberen &#xff08;test&#xff09;和Verhogen &#xff08;increment&#xff09;&#xff09;、是一种卓有成效的进程同步机制。 信号量-软件解决方案&#xff1a; 保证两个或多个代码…

记录一个Insert姿势引起的MySQL从库上查不到数据的问题

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 某测试环境的MySQL用了两台节点&#xff0c;主从同步结构。忽然有研发同学反映说MySQL的主从不同步了。他…

数据分析实战丨基于flask+pygal可视化分析sqlite中的数据

文章目录 写在前面实验目标项目框架实验内容1.配置实验环境2.查看sqlite3数据库的数据3.创建项目文件4.编写代码5.运行项目 运行结果写在后面 写在前面 本期内容&#xff1a; 基于FlaskPygal可视化分析Sqlite3中的数据 实验环境&#xff1a; pythonpygalflask 项目下载地址…

浅析链表结构

一、单向链表 C语言中数组是常用的一种数据类型&#xff0c;但可惜数组长度是固定大小的&#xff0c;不能动态扩展&#xff0c;使用起来有时不是很方便。然后就有了自定义的动态数组结构&#xff0c;动态数组就比较好用了&#xff0c;长度可以任意扩展&#xff0c;但还有一个问…

2024阿里云服务器ECS介绍_全方位解析_CPU性能详解

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

Ubuntu 在线Swap扩容

1. 查看本机swap空间 free -h 2. 找一个较大的高速盘&#xff0c;创建swap的空间 mkdir /swap cd /swap sudo dd if/dev/zero ofswapfile bs50M count1k3.建swapfile&#xff0c;大小为bs*count 50M * 1k 50G 4.标记为Swap文件&#xff0c;让系统能识别交换文件。 sudo mk…

C1-3.2 关于‘神经网络’

C1-3.2 关于‘神经网络’ 【注释】 彩色图像&#xff08;RGB&#xff09;由三原色构成&#xff0c;二维图像在任意一个点像素为立体三层结构&#xff0c;分别是红色、绿色、蓝色值&#xff0c;该值的范围在0∽255之间 1、全连接神经网络——整体架构 【注释】&#xff1a; …

科技顶天,市场立地 。璞华科技“顶天立地”的成长之路

科技顶天&#xff0c;市场立地。 几十年来&#xff0c;我们越来越深刻地认识到&#xff0c;这就是真理&#xff0c;质朴而深刻。尤其在当前特殊的国际国内商业环境中&#xff0c;这一理念不但没有过时&#xff0c;反而恰逢其时。有这么一家企业&#xff0c;一直践行“科技顶天…

分类预测 | Matlab实现RP-LSTM-Attention递归图优化长短期记忆神经网络注意力机制的数据分类预测【24年新算法】

分类预测 | Matlab实现RP-LSTM-Attention递归图优化长短期记忆神经网络注意力机制的数据分类预测【24年新算法】 目录 分类预测 | Matlab实现RP-LSTM-Attention递归图优化长短期记忆神经网络注意力机制的数据分类预测【24年新算法】分类效果基本描述模型描述程序设计参考资料 分…

2023极客大挑战web小记

拿到题目提示post传参还以为是道签到题 刚开始直接把自己极客大挑战的username以及password怼上去&#xff0c;但是不对。看看F12&#xff0c;有提示。 当一个搜索蜘蛛访问一个站点时&#xff0c;它会首先检查该站点根目录下是否存在robots.txt&#xff0c;如果存在&#xff0c…

近视的孩子用什么灯?学生考研护眼台灯推荐

随着时代快速发展&#xff0c;2022年我国近视人数达到了7亿&#xff0c;呈现低龄化趋势&#xff0c;儿童及青少年人数占了53.8%。现在学业负担都很重&#xff0c;每个家长都不希望自己的孩子近视或加深近视了&#xff0c;都会想尽一切办法保护视力。而护眼台灯就成了家长购买台…

智能路由器中的 dns.he.net可使用自定义域名的免费 DDNS 服务配置方法

今天介绍的这个是可以使用自定义域名同时支持使用二级域名的免费DDNS服务 dns.he.net的动态DDNS服务的配置方法, 这个服务相对还是比较稳定的, 其配置也和其他的DDNS服务有些不太一样, 首先他的主机名: 这里需要设置为登录后分配的区域域名: ipv6.he.net 然后就是 DDNS 用户…

Git新手?这篇文章带你飞!基础操作一网打尽!

推荐阅读 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;一&#xff09; 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;二&#xff09; 文章目录 推荐阅读Git初识Git啥是版本控制系统&#xff1f;&#xff1f;集中式VS分布式 git使用…

录屏怎么打开?看这里,录制视频不费事!

随着科技的快速发展&#xff0c;录屏已经成为人们日常生活中经常使用的功能。无论是录制游戏视频、教程讲解&#xff0c;还是录制在线会议&#xff0c;录屏软件都发挥着重要作用。然而&#xff0c;很多用户并不知道录屏怎么打开&#xff0c;以及如何使用它们。本文将介绍两种常…

【书生·浦语】大模型实战营——第四课作业

教程文档&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/self.md 基础作业需要构建数据集&#xff0c;微调模型&#xff0c;让其明白自己的弟位&#xff08;OvO&#xff01;&#xff09; 微调环境准备 进入开发机后&#xff0c;先bash&#xff0c;再创…