数据结构之归并排序算法【图文详解】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

在这里插入图片描述

                                           博主主页:LiUEEEEE
                                              C语言专栏
                                            数据结构专栏
                                         力扣牛客经典题目专栏

目录

  • 1、归并排序的基本思想
  • 2、归并排序的实现
    • 2.1. 归并排序的递归实现
    • 2.2. 归并排序的非递归实现
  • 3、归并排序非递归方法实现的常见问题
  • 4、结语

1、归并排序的基本思想


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



2、归并排序的实现


  归并排序的实现拥有两种方法:
  • 递归实现
  • 非递归实现

  但归根到底其主要思想不会发生变化,以下是归并排序的动态展示图:
在这里插入图片描述

2.1. 归并排序的递归实现


  如上文所展示的效果图可知:
  • 对于归并排序,需使用二叉树中后序的思想,将所给目标数组全部类二分,而后进行递归,当所递归数组个数为1时开始归并。
  • 将归并后的子数组复制到原数组中对应位置,并开启新一轮的归并,这就需要我们动态开辟一个第三方数组tmp来进行辅助。

  
  • 归并排序的递归实现代码如下所示:
void MergeSort(int* a, int* tmp, int begin, int end)
{
	if (begin >= end)
		return;
	int mid = (begin + end) / 2;

	MergeSort(a, tmp, begin, mid);
	MergeSort(a, tmp, mid + 1, end);

	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
		{
			tmp[i++] = a[begin2++];
		}
	}

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

	memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
}

2.2. 归并排序的非递归实现


  其思想与递归并无差别,区别在于操作方式:
  • 在递归实现中,我们使用类二分的方法将原目标数组分为2份依次进行二分的归并递归,而在非递归中,我们不再使用类二分的方法,而是直接在原数组上进行操作。
  • 在逻辑上认为原数组已经进行处于递归的过程,即:令gap = 1
  • 第一次对每一个元素进行归并,归并完成后,令 gap *= 2。
  • 第二次对每两个元素进行归并,归并完成后,令 gap *= 2。
  • 第n 次对每2^(n-1)个元素进行归并,归并完成后,令 gap *= 2。
  • 直到gap大于元素原本数组个数时,结束。
    在这里插入图片描述
  • 归并排序的非递归实现代码如下:
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("MergeSortNonR: malloc fail");
		return;
	}
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;

			if (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[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));
		}
		printf("\n");
		gap *= 2;
	}
	free(tmp);
	tmp = NULL;
}




3、归并排序非递归方法实现的常见问题


  在使用非递归方法实现归并排序时,我们通常无法精确掌握其归并数组的左右区间,例如下图:

在这里插入图片描述
  图中所展示的示例数组拥有十九个元素,但在归并过程中会发生越界行为,出现bug。

  但通过途中所展示我们不难发现,出现越界的数组一般为右子数组,当右子树组的右下标出现越界时,我们可直接对其右下标进行修正即可,当右子树组的左下标越界时,就说明左子数组已经归并完成,我们可直接跳出循环进行下一次归并,直到整个数组归并完成即可。




4、结语


在这里插入图片描述

  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

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

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

相关文章

【JS】详解reduce()方法及其奇技淫巧、性能

历史小剧场 或许到人生的最后一刻&#xff0c;他都不知道自己为什么会死&#xff0c;他永远也不会知道&#xff0c;在这个世界上&#xff0c;有着许多或明或暗的规则&#xff0c;必须适应&#xff0c;必须放弃原则&#xff0c;背离良知&#xff0c;与光同尘&#xff0c;否则你有…

make_ext4fs:not found

报错信息&#xff1a; 解决&#xff1a; sudo apt-get install android-tools-fsutils sudo apt-get install android-sdk-libsparse-utils sudo apt-get install android-sdk-ext4-utils

代码随想录训练营Day29

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、递增子序列二、全排列三、全排列2 前言 今天是跟着代码随想录刷题的第29天&#xff0c;今天主要学了以下几个内容&#xff1a;491.递增子序列、46.全排列、…

python中实现队列功能

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 python中实现队列功能 选择题 以下代码最后一次输出的结果是&#xff1f; from collections import deque queue deque() queue.append(1) queue.append(2) queue.append(3) print(【显示】…

惊呆了!六西格玛培训竟然这么强大!——张驰咨询

六西格玛&#xff0c;这个在业界久负盛名的管理理念&#xff0c;它的魅力太强大了。曾听闻它能帮助企业和个人提升竞争力&#xff0c;但当真正走进这个培训体系时&#xff0c;会发现它的影响力远超你的想象。 在六西格玛的指导下&#xff0c;企业实现了显著的转变。之前那些看…

微软云计算[1]之云计算平台、云操作系统Windows Azure

微软云计算平台 微软云计算平台微软的云计算技术Windows Azure组成 微软云操作系统Windows AzureWindows Azure概述Windows Azure计算服务Windows Azure存储服务全局命名空间体系架构存储域的层次结构双复制引擎文件流层分区层 Windows Azure ConnectWindows Azure CDNFabric控…

第二证券股市资讯:全球第二!英伟达市值再超苹果

昨夜&#xff0c;英伟达股价再度大涨。‍‍‍ 当地时间6月5日周三&#xff0c;美股三大股指全线收涨。到收盘&#xff0c;道指涨0.25%&#xff0c;纳指涨1.96%&#xff0c;标普500指数涨1.18%。 经济数据方面&#xff0c;美国5月ADP新增工作人数15.2万人&#xff0c;低于预期…

python书上的动物是啥

Python的创始人为Guido van Rossum。1989年圣诞节期间&#xff0c;在阿姆斯特丹&#xff0c;Guido为了打发圣诞节的无趣&#xff0c;决心开发一个新的脚本解释程序&#xff0c;做为ABC语言的一种继承。之所以选中Python作为程序的名字&#xff0c;是因为他是一个叫Monty Python…

【Python报错】AttributeError: ‘NoneType‘ object has no attribute ‘xxx‘

成功解决“AttributeError: ‘NoneType’ object has no attribute ‘xxx’”错误的全面指南 一、引言 在Python编程中&#xff0c;AttributeError是一种常见的异常类型&#xff0c;它通常表示尝试访问对象没有的属性或方法。而当我们看到错误消息“AttributeError: ‘NoneTyp…

基于springboot实现餐饮管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现餐饮管理系统演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率…

基于springboot实现民族婚纱预定系统项目【项目源码+论文说明】

基于springboot实现民族婚纱预定系统的设计演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本民族婚纱预定系统就是在这样的大环境下诞生&#xff0c;其可…

3. 使用tcpdump抓取rdma数据包

系列文章 第1章 多机多卡运行nccl-tests 和channel获取第2章 多机多卡nccl-tests 对比分析第3章 使用tcpdump抓取rdma数据包 目录 系列文章一、准备工作1. 源码编译tcpdump2. 安装wireshark 二、Tcpdump抓包三、Wireshark分析 一、准备工作 1. 源码编译tcpdump 使用 tcpdump…

一、【源码】创建简单的映射器代理工厂

源码地址&#xff1a;https://github.com/mybatis/mybatis-3/ 仓库地址&#xff1a;https://gitcode.net/qq_42665745/mybatis/-/tree/01-xxxDao-proxy 创建简单的映射器代理工厂 执行xxxDao.method()时都做了些什么&#xff1f; 原理是&#xff1a;首先定义Dao接口&#xff…

一周学会Django5 Python Web开发 - Django5内置Auth认证系统-用户登录实现

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计57条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

企业购买一套ABAQUS需要多少钱?ABAQUS价格解析

在高性能仿真分析领域&#xff0c;ABAQUS软件凭借其强大的非线性分析能力、精确的求解精度以及广泛的应用范围&#xff0c;成为众多企业和研究机构的首选工具。然而&#xff0c;对于想要采购ABAQUS的企业来说&#xff0c;了解其价格体系是做出投资决策前的关键一步。亿达四方&a…

增值税发票OCR识别功能介绍

OCR增值税发票识别功能介绍如下&#xff1a; 一、技术原理 OCR增值税发票识别系统基于光学字符识别&#xff08;OCR&#xff09;技术和人工智能的支持&#xff0c;将传统纸质发票的信息自动转换为计算机可以读取的数字信息。具体技术流程包括&#xff1a; 图像预处理&#x…

Spring Boot项目中,如何在yml配置文件中读取maven pom.xml文件中的properties标签下的属性值

一、前言 在最近的项目开发过程中&#xff0c;有一个需求&#xff0c;需要在Spring Boot项目的yml配置文件中读取到mave的 pom.xml文件中的properties标签下的属性值&#xff0c;这个要怎么实现呢&#xff1f; 二、技术实践 pom.xml文件中增加测试属性 <properties><…

Vue06-el与data的两种写法

一、el属性 用来指示vue编译器从什么地方开始解析 vue的语法&#xff0c;可以说是一个占位符。 1-1、写法一 1-2、写法二 当不使用el属性的时候&#xff1a; 两种写法都可以。 v.$mount(#root);写法的好处&#xff1a;比较灵活&#xff1a; 二、data的两种写法 2-1、对象式…

基于web的垃圾分类回收系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;公告管理&#xff0c;运输管理&#xff0c;基础数据管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;运输管理&#xff0c;公告…

麒麟桌面操作系统KYLINOS 2403安装部署

原文链接&#xff1a;麒麟桌面操作系统KYLINOS 2403安装部署 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于麒麟桌面操作系统2403的安装部署文章。麒麟操作系统是中国自主研发的Linux发行版&#xff0c;以其安全性和稳定性受到广泛关注和使用。本文将详细介绍如…