数据结构系列-归并排序

news2024/11/15 9:09:14

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

归并排序

递归版本

首先,我们来看一下归并的示意图:

这是归并排序当中分解的过程。 然后便是两个两个进行排序,组合的过程。

归并完美的诠释了“分治的思想”,分治分治,分而治之,我们将一个大的问题不断地分为一个个小的子问题,然后通过解决子问题的目的对大问题进行解决。

为了更好的理解,接下来,请看下面的这一张动图: 

我们在这张图中可以理解到归并的实现逻辑,它的实现,需要借助一个新的数组,并两个,四个,逐渐进行排序。

  • 用malloc函数开辟一个新的数组,并对数组进行检查
  • 确定最小子问题(当只有一个元素的时候就不用在进行递归,一个就是有序的)
  • 进行递归找到最小子区间(第一张示意图的最后一行)
  • 然后其实就是两个有序数组的合并,合并之后再进行拷贝,然后又进行合并,继续拷贝。

首先,我们给到归并排序在.h文件中的定义。

//Sort.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
void MergeSort(int* a, int n);

接下来,我们在.c文件中进行归并排序的实现

首先,我们写一下归并排序的整体框架:

void MergeSort(int* a, int begin, int end, int* tmp)
{
	//......
}
void MergeSort(int* a, int n)
{
	//开辟数组
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp = NULL)
	{
		perror("malloc fail");
		return;
	}
	_MergeSort(a, 0, n - 1, tmp);

	//清除开辟的数组
	free(tmp);
	tmp = NULL;
}

接下来,我们在子函数当中,对代码进行完善 

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin == end)
		return;

	//定义初始变量
	int mid = (begin + end) / 2;
	int begin1 = begin, end1 = mid;
	int begin2 = mid+1, end2 = end;

	_MergeSort(a, begin1, end1, tmp);
	_MergeSort(a, begin2, end2, tmp);
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] >= a[begin2])
		{
			tmp[i++] = a[begin2++];
		}
		else
		{
			tmp[i++] = a[begin1++];
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}
	_MergeSort(a, 0, n-1, tmp);
	
	free(tmp);
	tmp = NULL;
}

接下来是归并排序的测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
int main()
{
	int a[] = { 5,1,2,7,5,6,2,5,3,9,7 };
	MergeSort(a, sizeof(a) / sizeof(int));
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

非递归版本

  • 我们设置一个gap表示begin1,end1,begin2,end2
  • 非递归版本主要就是通过控制gap来实现递归

 

void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			int begin1 = i, end1 = begin1 + gap - 1;
			int begin2 = begin1 + gap, end2 = begin2 + gap - 1;
			//

			if (end1 >= n || begin2 >= n)
			{
				break;
			}
			if (end2 >= n)
				end2 = n - 1;
			int j = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] >= a[begin2])
				{
					tmp[j++] = a[begin2++];
				}
				else
				{
					tmp[j++] = a[begin1++];
				}
			}
			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;
	}

}
  1.  我们先设定一个gap=1(这个代表只有一个元素,这个自然是有序的)
  2. 然后我们令gap*=2,实现gap的递增,从而扩大排序的范围

 对于归并排序而言,

它的时间复杂度是O(N*logN)

它的空间复杂度是O(N)

稳定性:稳定

 归并排序的主要缺点就是空间复杂度较大,需要开辟新的空间。

好了,这个就是归并排序的所有内容。

归并排序此外还被用到了文件排序当中,这个我们后面会进行讲解。

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

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

相关文章

docker镜像,ip,端口映射,持久化

docker 镜像的迁移&#xff1a;导出和导入镜像 查看镜像&#xff1a; [rootdocker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 5d0da3dc9764 2 years ago 231MB 打包 将镜像打包&#xff0c;找到save,可以将…

远程在电脑上玩PS5《黑神话:悟空》?借助极空间实现PS5远程串流攻略

远程在电脑上玩PS5《黑神话&#xff1a;悟空》&#xff1f;借助极空间实现PS5远程串流攻略 哈喽小伙伴们好&#xff0c;我是Stark-C~ 这两天的《黑神话&#xff1a;悟空》可谓是火爆出圈呀&#xff01;虽说我也是第一时间体验到了这款可以说是划时代意义的首款国产3A大作&…

maven 依赖管理(4)

依赖就是项目里运行的jar 一个项目可以设置多个依赖 这种的 1.依赖传递 直接依赖&#xff1a;就是当前自己的项目pom里的依赖 间接依赖&#xff1a;在自己pom文件引入别人的项目 就能共享到别人项目的依赖 2.依赖传递冲突问题 路径优先&#xff1a;出现相同依赖&#xff0…

华为数通方向HCIP-DataCom H12-821题库(更新单选真题:1-10)

第1题 1、下面是一台路由器的部分配置,关于该配置描述正确的是? [HUAWEllact number 2001 [HUAWEl-acl-basic-2001]rule 0 permit source 1.1.1.1 0 [HUAWEl-acl-basic-2001]rule 1 deny source 1.1.1.0 0 [HUAWEl-acl-basic-2001]rule

SSRF+Redis+Fastcgi

目录 1、打redis 2、打fastcgi 3、SSRF绕过 4、SSRF防御 1、打redis ssrfme靶场实战 页面直接给出了代码&#xff0c;过滤了file: dict ,等等 但是下面我们看到只要有info就能打印phpinfo() 通过phpinfo()打印的信息&#xff0c;发现有内网其他服务器的ip 直接访问 发现…

漏洞挖掘 | 浅谈一次edusrc文件上传成功getshell

0x1 前言 这里记录一下我在微信小程序挖人社局等一些人力资源和社会保障部信息中心漏洞&#xff0c;人社这类漏洞相对于web应用端的漏洞来讲要好挖很多&#xff0c;里面的WAF过滤等一些验证也少。比如你在开始学习src漏洞挖掘&#xff0c;就可以从微信小程序下手。 一般像这类…

Python编码系列—Python CI/CD 实战:构建高效的自动化流程

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

(7)JavaSE:注解与反射

一、注解 1.1什么是注解 Annotation 是从JDK5.0开始引入的新技术 。 作用: &#xff08;1&#xff09;不是程序本身 , 可以对程序作出解释.(这一点和注释(comment)没什么区别) &#xff08;2&#xff09;可以被其他程序(比如:编译器等)读取.使用范围&#xff1a; &#xff0…

Python进阶(十一)】—— Pandas和Seaborn可视化

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

数字化与进制转换

1.数字化是什么&#xff1f; 数字化是将事物的属性转化为计算机可处理对象的过程。 2.数字化的好处&#xff1f; 可以让我们的生活&#xff0c;学习和工作更加便捷&#xff0c;大大提升我们学习和工作的效率。 3.如何将采集到的数据进行数字化&#xff1f; 可以通过两种信…

运维的利器–监控–zabbix–第三步:配置zabbix–网络–原理:通过ping实现网络连通性监控

文章目录 通过ping实现网络连通性监控1、参数说明2、建立监控项3、创建图形 通过ping实现网络连通性监控 1、参数说明 ICMPPING[,,,,]通过ICMP ping检查主机是否可以访问。 target-目标IP或者域名 packets-数据包数量 interval-间隔时间&#xff08;毫秒&#xff09; size-数…

Windows系统电脑安装多个Tomcat服务教程

文章目录 引言I 下载Tomcat安装包II 安装tomcat多个tomcat服务重命名Tomcat应用程序安装Tomcat服务安装和配置JRE配置服务信息III 知识扩展: windows RDP远程访问资源引言 需求: 基于Tomcat部署多个服务和站点都一台Windows机器 I 下载Tomcat安装包 https://tomcat.apache.o…

LabVIEW高速数据采集关键问题

在LabVIEW进行高速数据采集时&#xff0c;需要关注以下几个关键问题&#xff1a; 数据采集硬件的选择: 高速数据采集需要高性能的数据采集硬件&#xff0c;例如NI PXIe、USB DAQ等模块。硬件的选择应根据采集速率、通道数、精度、以及应用场景的具体需求来确定。 采集速率与带…

认知杂谈22

今天分享 有人说的一段争议性的话 I I 私人空间&#xff0c;成长的温床 咱一说到成长啊&#xff0c;可不能小瞧了外部环境对咱的影响。这环境啊&#xff0c;那可不是无关紧要的事儿&#xff0c;实际上呢&#xff0c;它对咱的成长起着特别关键的作用。你就想想看&#xff0c…

ssrf漏洞复现分析(1)

目录 Web-ssrfme 搭建环境 分析 ssrf攻击本地fastcgi漏洞复现 Web-ssrfme 搭建环境 这里我们使用的是docker环境&#xff0c;只需要把docker压缩包下载到Ubuntu下解压后执行命令即可&#xff0c; docker-compose up -d 但是我的环境中不知道是缺少什么东西&#xff0c;他…

姿态识别 python 效果好,提供多种精准模型

该项目是一款基于Python的AI健身教练系统&#xff0c;它利用先进的姿态识别技术来帮助用户进行正确的运动姿势训练。该系统可以识别并纠正用户在做特定运动时的姿势&#xff0c;比如深蹲、仰卧起坐、步行等。 技术栈&#xff1a; 编程语言&#xff1a;Python深度学习框架&…

深度理解指针(3)

hello&#xff0c;各位小伙伴们在上期的最后我们了解到了指针数组&#xff0c;是用来存储指针的数组。这期我们将会学习深度理解指针&#xff08;3&#xff09;有关指针的内容&#xff0c;仍然与数组分不开&#xff0c;让我们踏上此次列车来进行新的旅途吧&#xff01; 目录 字…

【实施】软件实施方案(word套用)

软件实施方案 二、 项目介绍 三、 项目实施 四、 项目实施计划 五、 人员培训 六、 项目验收 七、 售后服务 八、 项目保障措施 软件开发全套资料获取&#xff1a;&#xff08;本文末个人名片也可直接获取&#xff09; 软件产品&#xff0c;特别是行业解决方案软件产品不同于一…

【ES6】使用Proxy实现单例模式

前言 由于JS没有private关键字&#xff0c;无法私有化构造器&#xff0c;所以下面代码无法限制&#xff1a; class Person {constructor() {console.log("Person created");} }const p1 new Person(); const p2 new Person();console.log(p1 p2); // false实现 …

【机器学习】小样本学习的实战技巧:如何在数据稀缺中取得突破

我的主页&#xff1a;2的n次方_ 在机器学习领域&#xff0c;充足的标注数据通常是构建高性能模型的基础。然而&#xff0c;在许多实际应用中&#xff0c;数据稀缺的问题普遍存在&#xff0c;如医疗影像分析、药物研发、少见语言处理等领域。小样本学习&#xff08;Few-Shot Le…