归并排序C语言

news2025/2/22 3:12:14

基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

0f1d3fcc5e85076ed0445cba68d5cb7c.png

 归并排序其实就是等分分割数组,直到分割后的数组有序再将这分割的两个数组归并到一个新的数组里,再拷贝到原数组中。这里就与二叉树的后序遍历极为相似,分割的数组只有一个数时就默认有序了,再合并之后一步步的递归回去。 

 

代码(递归)

void _MergeSort(int* arr, int left, int right,int* tmp)
{
	if (left == right)//不可能分割出不存在的区间
		return;
	int midi = (left + right) / 2;
	_MergeSort(arr, left, midi, tmp);//分割归并左部分
	_MergeSort(arr, midi + 1, right, tmp);//分割归并右部分

	//归并(begin1和end2之间的数)即left和right之间的数
	int i = 0;//临时数组下标
	int begin1 = left, end1 = midi;
	int begin2 = midi + 1, end2 = right;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] < arr[begin2])
			tmp[i++] = arr[begin1++];
		else
			tmp[i++] = arr[begin2++];
	}
	while (begin1 <= end1)
	{
		tmp[i++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = arr[begin2++];
	}

	memcpy(arr+left, tmp, sizeof(int) * i);//归并一次就拷贝一次

}
void MergeSort(int* arr, int left, int right)
{
	int* tmp = (int*)malloc(sizeof(int*) * (right + 1));
	_MergeSort(arr, 0, right,tmp);
	free(tmp);
}

 

代码1(非递归)

void _MergeSort(int* arr, int left, int right, int* tmp)
{

	int gap = 1;//每一组的数据个数
	while (gap < right)
	{
		
		for (int i = 0; i <= right; i += 2 * gap)//两两归并,遍历整个数组
		{
			int j = 0;//临时数组的下标
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;

			if (end1 > right || begin2 > right)
				break;
			if (end2 > right)
			{
				end2 = right;
			}

			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++];
			}
			memcpy(arr + i, tmp, sizeof(int) * j);//归并一次拷贝一次
		}
		gap *= 2;
	}

}

非递归就要知道该代码原来递归是怎么走的,递归的部分实际上是在一直分割成两部分,直到不能再分割了以后,就开始合并到tmp临时数组里,所以非递归的写法实际就也是分组执行,先是单个数是一组,两两一组进行比较拷贝,原先拷贝好的就可以是一组了,此时每组就有两个数是有序的,再两两一组,两组再进行拷贝,此时拷贝好的一组就有四个有序的数了,再进行四四一组.......

 

但是这可能存在越界的情况,两组数据拷贝,极有可能就越界,而且存在三种越界的情况:

5eab0d1a341845ad83c158eeff837332.png

 而上面的一二两种情况又可以看作一种:多余了已经有序的一组(不到一组)此时该组已经有序了,所以也不用进行归并了,直接放在原数组中就行了,但是你memcpy拷贝数组就得一组组的拷贝了,不能归并完整个数组以后再全部拷贝到原数组。

而第三种情况就是多了不仅仅一组的数据但是却又不够两组,此时就不能说这一组半是有序的,所以就重行划区间,end2就指向最后一个数的下标,将这半组也看成一组,两两拷贝数据成有序。

 

代码2(非递归) 

void _MergeSort(int* arr, int left, int right, int* tmp)
{
	int gap = 1;//每一组的数据个数
	while (gap < right)
	{
		int j = 0;//临时数组下标
		for (int i = 0; i <= right; i += 2 * gap)//两两归并整个数组
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			if (end1 > right)
			{
				end1 = right;
				begin2 = end2 + 1;//不存在的区间
			}
			else if(begin2 > right)
			{
				begin2 = end2 + 1;//不存在的区间
			}
			else if (end2 > right)
			{
				end2 = right;
			}
			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++];
			}
		}
		memcpy(arr, tmp, sizeof(int) * j);//一次拷贝整个数组数据
		gap *= 2;
	}

}

这就是可以一次拷贝整个数组的情况,即当遇到越界的情况就就调整范围,继续拷贝。

0beea402e2354a38b54fa0cf27fc5fae.jpeg

 

 

 

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

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

相关文章

火焰图性能监测

准备工作——安装perf 我是在github的codespace上搞的&#xff0c;可以按下面的方式安装perf&#xff1a; sudo apt install linux-tools-generic sudo apt install linux-cloud-tools-azure参考在WSL2中使用perf性能剖析工具 测试程序——简单的C程序 弄一个无限循环的C程…

SpringMVC的数据响应-19

新的上面也是相当于放到域当中了 sel表达式&#xff0c;取你键值对的名称&#xff0c;使用前创造jsp文件 这个地域里面放什么都行 上面的内容也是ModelandView弄个文件记下来 1、新的方法&#xff0c;你在参数这里可以加一个ModelandView 往里面放点数据和视图名称 这种方法也能…

【hadoop】centos7.6+hadoop3.1.1搭建分布式hadoop环境——包含各类问题解决方案

本文针对centos7.4即以上版本的hadoop环境搭建&#xff0c;因为这部分搭建是个很复杂且很容易出错的内容&#xff0c;所以在结合了多种搭建方案后给出最适宜当前版本的搭建。 目录 一、准备阶段环境要求软件版本要求配置部署环境 二、部署阶段部署ZooKeeper安装ZooKeeper并配置…

华为云CodeArts Check代码检查新手操作指南

代码检查服务是基于云端实现代码质量管理的服务&#xff0c;软件开发者可在编码完成后执行多语言的代码静态检查和安全检查&#xff0c;获取全面的质量报告&#xff0c;并提供缺陷的分组查看与改进建议&#xff0c;有效管控代码质量&#xff0c;确保产品原生高质量和产品安全&a…

【文末福利】我用英飞凌的PSoC™ 62搞了点智能家居的创意

【英飞凌创意创客大赛】基于Infineon和ChatGPT的人工智能语音小管家 概要 本文给大家介绍一个Infineon和ChatGPT的人工智能语音小管家项目&#xff0c;该项目是博主架构师李肯参加由RT-Thread与英飞凌联合举办的2023英飞凌创意创客大赛的参赛项目&#xff0c;旨在探索智能硬件智…

微服务day1

一、认识微服务 1、单体架构 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 优点 架构简单部署成本低 缺点 耦合度高 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fPfsQXAn-1689593800699)(https://picture.wangkay.tec…

GPT-1,GPT-2,GPT-3 InstructGPT论文学习笔记

Gpt-1 论文&#xff1a;《Improving Language Understanding by Generative Pre-Training》 GPT-1网络结构 无监督,使用12层transforer decoder结构,每一层维度是768,12个注意力heads token embedding矩阵,经过transformer decoder处理后,经过线性层和softmax层,得到下一个toke…

自定义一个SpringBoot starter 怎么实现

文章目录 1、创建一个空项目2、在新建的空项目中添加starter模块3、添加autoconfigure模块4、配置starter模块的pom文件5、配置autoconfigure模块1. 配置pom依赖2、创建xxProperties配置类3、创建服务提供类xxxService4、创建自动配置类xxxGenerateAutoConfiguration5 、META-I…

pgrouting 管线 联通分析

背景描述 啦啦啦啦&#xff0c;然后拉拉阿里&#xff0c;然后啦啦啦&#xff0c;最后就写了这个记录一下 数据准备 1 管线数据 数据要求&#xff08;拓扑检查&#xff09; 数据没有重叠要求 数据悬挂点问题得到合理结局&#xff0c;不存在数据连接点不一样的线 数据能按…

C. Fighting Tournament - 模拟+思维

分析&#xff1a; 每次两个数比较&#xff0c;大的留下&#xff0c;小的放后面&#xff0c;可以发现只要最大的到了第一位就只能是它赢&#xff0c;因此统计第一次遍历所有数组元素的赢的次数&#xff0c;如果查询是最大的数呢么就在加上k-n&#xff0c;赛时代码写的一团乱&…

适合投资者的交易策略,4步找到

在外汇交易市场中&#xff0c;根据市场情况和个人投资目标&#xff0c;制定灵活的交易策略是至关重要的。Forexclub认为投资者可以通过结合多种交易策略&#xff0c;打造出全面、科学且适合自己的外汇交易策略。 首先&#xff0c;基于技术指标的交易策略是判断市场趋势和转折点…

「数字化制造」 是如何让制造过程信息化的?

「数字化制造」 是如何让制造过程信息化的&#xff1f; 数字化制造是指利用数字技术和信息化手段来实现制造过程的智能化、自动化和高效化。 它通过将传感器、物联网、云计算、大数据分析、人工智能等先进技术与制造业相结合&#xff0c;实现生产过程的数字化、网络化和智能化…

【原创】实现ChatGPT中Transformer模型之Encoder-Decoder

作者&#xff1a;黑夜路人 时间&#xff1a;2023年7月 Transformer Block &#xff08;通用块&#xff09;实现 看以上整个链路图&#xff0c;其实我们可以很清晰看到这心其实在Encoder环节里面主要是有几个大环节&#xff0c;每一层主要的核心作用如下&#xff1a; Multi-he…

Flask 分页Demo

项目结构 app.py from flask import Flask, render_template, requestapp Flask(__name__)books [{title: Book 1, author: Author 1, year: 2020},{title: Book 2, author: Author 2, year: 2021},{title: Book 3, author: Author 3, year: 2022},{title: Book 4, author: …

《面试1v1》面试官让我讲一下Kafka的性能哪里好

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

公钥加密之『迪菲–赫尔曼密钥交换』,颜色混合的把戏

前奏&#xff1a; 迪菲-赫尔曼密钥交换是一种安全协议。它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。 颜色混合&#xff1a; 如图所示&#xff0c;蛇和老鼠要交换一个共享密钥&…

Springboot热部署相关功能

文章目录 前言一、Springboot如何在IDEA中开启热部署二、热部署的相关知识1.热部署的范围2.关闭热部署 前言 环境是Mac电脑下的IDEA 2023.1.X版本 如何在修改程序后自动进行加载修改后的程序而不是重启加载所有资源而更新程序&#xff0c;这就使用到了Springboot相关的热部署功…

120页商业银行企业级IT架构规划ppt

导读&#xff1a;原文《商业银行企业级IT架构规划ppt》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需获取完整的电…

2023年7月17日,比较器,TreeMap底层,LinkedHashMap,Set接口

比较器 Comparator是外部比较器&#xff0c;用于比较来对象与对象之间的&#xff0c;两个对象进行比较&#xff0c;多用于集合排序 Comparable可以认为是一个内比较器&#xff0c;根据对象某一属性进行排序的。 1. 使用场景 ​ 内置比较器&#xff08;Comparable&#xff09;的…

Windows10下ChatGLM2-6B模型本地化安装部署教程图解

随着人工智能技术的不断发展&#xff0c;自然语言处理模型在研究和应用领域备受瞩目。ChatGLM2-6B模型作为其中的一员&#xff0c;以其强大的聊天和问答能力备受关注&#xff0c;并且最突出的优点是性能出色且轻量化。然而&#xff0c;通过云GPU部署安装模型可能需要支付相应的…