排序 “肆” 之归并排序

news2025/1/16 16:02:05

1. 归并排序

1.1 原理介绍

归并排序的基本原理是将一个未排序的数组分解较小的子数组,然后递归地对这些子数组进行排序,最后再将排好序的子数组合并成一个有序数组。其核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列

其主要步骤包括:

  1. 分割:将原始数组分割为较小的子数组,直到每个子数组只包含一个元素。
  2. 合并:逐个比较两个子数组的元素,并按顺序合并它们。

1.2 主要步骤

详细步骤:

  1. 分解:将待排序数组分解成两个大致相等的子数组,直到子数组中只有一个元素为止。这一步是通过递归实现的。
  2. 合并:将两个已排序的子数组合并成一个有序数组。在合并过程中,创建一个临时数组,比较两个子数组的元素,将较小的元素依次放入临时数组中。
  3. 递归合并:重复步骤 2,直到所有子数组都合并成一个完整的有序数组。

下面是一个示例来说明归并排序的详细步骤:

  • 假设待排序数组为 [38, 27, 43, 3, 9, 82, 10]。
  1. 初始状态:原始数组为 [38, 27, 43, 3, 9, 82, 10]。
  2. 第一次分解:将数组分解为 [38, 27, 43, 3] 和 [9, 82, 10] 两个子数组。
  3. 对左边子数组进行排序:分解左边子数组 [38, 27, 43, 3],分解为 [38, 27] 和 [43, 3];继续分解为 [38] 和 [27],以及 [43] 和 [3]。 对每个子数组进行合并排序,得到 [27, 38] 和 [3, 43]。最终合并左边子数组得到 [3, 27, 38, 43]。
  4. 对右边子数组进行排序:分解右边子数组 [9, 82, 10],分解为 [9] 和 [82, 10]。继续分解为 [82] 和 [10]。对每个子数组进行合并排序,得到 [10, 82]。最终合并右边子数组得到 [9, 10, 82]。
  5. 合并左右子数组:将左边子数组 [3, 27, 38, 43] 和右边子数组 [9, 10, 82] 合并,依次比较两个子数组的元素,将较小的元素放入临时数组中。最终得到合并后的有序数组 [3, 9, 10, 27, 38, 43, 82]。
  6. 最终结果:经过以上步骤,我们得到了完整的有序数组 [3, 9, 10, 27, 38, 43, 82]。

 

1.3 代码示例

void _MergeSort(int* a, int begin, int end, int* tmp)
{
	if (begin >= end)
		return;

	int mid = (begin + end) / 2;
	//递归排序左右两部分
	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid + 1, end, tmp);

	//合并两个有序数组
	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, 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);
}

//测试
int main()
{
	int a[] = { 2,4,6,1,5,3,9,7,0,8 };
	int n = sizeof(a) / sizeof(int);

	printf("原数组为:");
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}

	MergeSort(a, n);

	printf("\n排序后数组为:");
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	return 0;
}

 

1.4 特性总结

  1. 稳定性:归并排序是一种稳定的排序算法,相同元素的相对位置在排序前后不会改变。
  2. 时间复杂度:归并排序的时间复杂度为 O(N*log N),其中 N 是待排序数组的长度。
  3. 空间复杂度:归并排序的空间复杂度为 O(N),需要额外的空间来存储临时数组。
  4. 适用性:归并排序适用于各种数据规模的排序,且在处理大规模数据时表现良好。

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

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

相关文章

C++链表操作入门

数据结构基础&#xff1a;链表操作入门 数据结构基础&#xff1a;链表操作入门链表的基本概念链表的基本操作输出链表插入节点删除节点查找值 完整的链表操作示例结语 数据结构基础&#xff1a;链表操作入门 在计算机科学中&#xff0c;数据结构是组织和存储数据的方式&#x…

监控上网行为的软件 五款上网行为监控软件推荐

在这个数字化时代&#xff0c;员工上网行为的管理与监控变得越来越重要。市面上涌现出众多监控员工上网的软件&#xff0c;它们各具特色&#xff0c;各有千秋。接下来&#xff0c;就让我们一起探索一下这些神奇的软件吧&#xff01; 1、安企神点击领取免费试用版 这是一款功能…

LMDeploy量化部署LLMVLM实践-笔记五

本次课程由西北工业大学博士生、书生浦源挑战赛冠军队伍队长、第一期书生浦语大模型实战营优秀学员【安泓郡】讲解【OpenCompass 大模型评测实战】课程 课程视频&#xff1a;https://www.bilibili.com/video/BV1tr421x75B/ 课程文档&#xff1a;https://github.com/InternLM/…

12 内核开发-任务调度之tasklet

12 内核开发-任务调度之tasklet 课程简介&#xff1a; Linux内核开发入门是一门旨在帮助学习者从最基本的知识开始学习Linux内核开发的入门课程。该课程旨在为对Linux内核开发感兴趣的初学者提供一个扎实的基础&#xff0c;让他们能够理解和参与到Linux内核的开发过程中。 课…

C++系列-命名空间

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 命名空间 在C/C中&#xff0c;变量&#xff0c;函数和后面要学到的类都是大量存在的&#xff0c;这些变量&#xff0c;函数和类的名称都存在于全局作用域中&#xff0c;可能会导…

【Linux系统化学习】生产者消费者模型(阻塞队列和环形队列)

目录 生产者消费者模型 什么是生产者消费者模型 为什么要使用生产者消费者模型 生产者消费者模型的优点 为什么生产者和生产者要互斥&#xff1f; 为什么消费者和消费者要互斥&#xff1f; 为什么生产者和消费者既是互斥又是同步&#xff1f; 基于BlockingQueue的生产者…

第四百八十一回

文章目录 1. 概念介绍2. 使用方法2.1 固定样式2.2 自定义样式 3. 示例代码4. 内容总结 我们在上一章回中介绍了"GetMaterialApp组件"相关的内容&#xff0c;本章回中将介绍使用get显示SnackBar.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在介…

Pandas 2.2 中文官方教程和指南(十一·一)

原文&#xff1a;pandas.pydata.org/docs/ PyArrow 功能 原文&#xff1a;pandas.pydata.org/docs/user_guide/pyarrow.html pandas 可以利用PyArrow来扩展功能并改善各种 API 的性能。这包括&#xff1a; 与 NumPy 相比&#xff0c;拥有更广泛的数据类型 对所有数据类型支持缺…

matlab新手快速上手3(差分进化算法)

本文用经典差分进化框架模板&#xff0c;对matlab新手友好&#xff0c;快速上手看懂matlab代码&#xff0c;快速应用实践&#xff0c;源代码在文末给出。 差分进化算法定义&#xff1a; 差分进化算法&#xff08;Differential Evolution&#xff0c;简称DE算法&#xff09;是…

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

基于springboot实现企业oa管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足&#xff0c;创建了一个计算机管理企业OA管理系统的方案…

SVGDreamer: 文本引导矢量图形合成

现有的 Text-to-SVG 方法还存在两个限制&#xff1a;1.生成的矢量图缺少编辑性&#xff1b;2. 难以生成高质量和多样性的结果。为了解决这些限制&#xff0c;作者提出了一种新的文本引导矢量图形合成方法&#xff1a;SVGDreamer。 论文题目&#xff1a; SVGDreamer: Text Guid…

❤mac使用Idea工具

❤mac使用Idea工具 1、安装 直接跳过&#xff0c;文章有 &#xff08;点击跳转&#xff09; 给自己的mac系统上安装java环境 2、使用 快捷键 Command , 系统首选项 设置Idea连接数据库 打开右侧的database&#xff08;或菜单里&#xff09;连接数据库&#xff0c;根据提…

Zabbix 安装部署说明文档

Zabbix是一个开源的网络监控和管理系统&#xff0c;其架构设计用于提供企业级的监控解决方案。以下是Zabbix的主要组件&#xff1a; 1.Zabbix Server&#xff1a;这是Zabbix系统的核心组件&#xff0c;负责接收Agent程序报告的系统可用性、系统完整性和统计数据。Zabbix Serve…

架构师系列- JVM(三)- 类加载

通过字节码&#xff0c;我们了解了class文件的结构 通过运行数据区&#xff0c;我们了解了jvm内部的内存划分及结构 接下来&#xff0c;让我们看看&#xff0c;字节码怎么进入jvm的内存空间&#xff0c;各自进入那个空间&#xff0c;以及怎么跑起来。 4.1 加载 4.1.1 概述 …

基于FastGPT搭建知识库问答系统

什么是 FastGPT &#xff1f; FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; FastGPT 允许用户构建本地知识库&#xff0c;…

创新书荐|用《创新者的窘境》指导企业应对AI颠覆技术避免被颠覆

如何利用《创新者的窘境》应对AI的颠覆性技术时&#xff0c;了解并实施正确的战略对于确保企业在动荡的市场环境中保持增长和竞争力至关重要。我们分析了市场领导者和初创公司如何利用AI开辟新的增长路径&#xff0c;以及企业如何在技术革命中维持竞争优势。想要深入了解并实践…

[C++ QT项目实战]----C++ QT系统登陆界面设计

前言 在C QT项目开发过程中&#xff0c;设计系统登录界面可以使用QT框架来实现。以下是一个简单的系统登录界面设计示例&#xff1a; 创建登录界面UI&#xff1a;可以使用QT Designer来设计登录界面的UI&#xff0c;包括用户名输入框、密码输入框、登录按钮等。在QT Designer中…

Linux下软硬链接和动静态库制作详解

目录 前言 软硬链接 概念 软链接的创建 硬链接的创建 软硬链接的本质区别 理解软链接 理解硬链接 小结 动静态库 概念 动静态库的制作 静态库的制作 动态库的制作 前言 本文涉及到inode和地址空间等相关概念&#xff0c;不知道的小伙伴可以先阅读以下两篇文章…

实习算法准备之BFSDFS

这里写目录标题 1 理论1.1 BFS框架 2 例题2.1 二叉树的最小高度2.2 打开转盘锁2.3 滑动谜题 1 理论 BFS和DFS是两个遍历算法&#xff0c;其中DFS之前已经接触过&#xff0c;就是回溯&#xff0c;忘记的话请回顾回溯篇的例题&#xff08;全排列&#xff0c;N皇后&#xff09; B…

力扣数据库题库学习(4.23日)

610. 判断三角形 问题链接 解题思路 题目要求&#xff1a;对每三个线段报告它们是否可以形成一个三角形。以 任意顺序 返回结果表。 对于三个线段能否组成三角形的判定&#xff1a;任意两边之和大于第三边&#xff0c;对于这个表内的记录&#xff0c;要求就是&#xff08;x…