C语言数据结构(11)——归并排序

欢迎来到博主的专栏C语言数据结构
博主ID:代码小豪

文章目录

    • 归并排序
      • 两个有序数组的合并
      • 归并排序
    • 归并排序的代码

归并排序

两个有序数组的合并

当前有两个有序数组arr1和arr2,我们创建一个可以容纳arr1和arr2同等元素个数的新数组arr。
在这里插入图片描述

让一个指针指向arr1的队首,一个指针指向arr2的队首,还有一个指针指向arr的队首。依次对比两个数组之间的值的大小,将数据较小的值放入arr中,再将对应的指针指向下一个元素。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时arr2已经遍历完了,将arr1的剩余数据全部拷贝到arr中。
在这里插入图片描述
在这里插入图片描述
可以发现,这种方法将有序数组合并之后任然是一个有序的数组,这是否说明,我们可以利用数组合并的方式实现一种排序算法呢?

在这里插入图片描述
这是一个无序数组arr,但是将这个数组分为两半。
在这里插入图片描述
就可以将两部分合并成一个有序的数组。

但是绝大多数的无序数组都无法找到这个分界线,所以想要利用合并有序数组完成排序,就需要先将整体的数组分为两部分,其中一部分是有序数组,另外一部分也是有序数组,然后再将这两个有序数组合并,完成排序。

当数组中的元素个数越来越多,那么出现两个有序数组的概率就会越来越小,这是显而易见的现象,那么如果反过来想呢?若是数组中的数据只有两个,那么出现两个有序数组的概率是百分之百。
在这里插入图片描述
如果现在有四个元素组成的数组,那么由此法拆解后的子数组为:
在这里插入图片描述
为什么要将一个数组分成N个大小为1的子序列呢?

可以发现,这些子序列都是有序的,那么将这些子序列进行有序合并,合并后的序列也就是有序的序列了。

相信大家再学高数的极限的时候都看过这么一句话:

一尺之捶,日取其半,万世不竭

意思就是将一个木棒,每天截取他的一半,永远都截不完。

当然数组是不会取不完的,如果将一个数组一直分成两半,最后就会得到一个元素组成的子序列。
在这里插入图片描述

现在有N个元素为1的子序列,将两两相邻的子序列合并成有序序列。直到所有子序列构成一个数组为止

例如:
在这里插入图片描述

归并排序

将前3个操作联系起来就能实现归并排序。

归并排序的定义如下:

设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的子序列,再两两合并……如此重复,直到得到一个长度为n的有序序列为止

归并排序的步骤如下:
(1)将整个数组二分递归,直到不可分为止(单数据序列)
(2)由递归堆栈开始合并有序序列,最后将合并完成的数组拷贝到原数组。

这里讲讲合并数组时的递归堆栈,先通过递归将整个数组拆分。
在这里插入图片描述
这个分解的方式与二叉树一致。完成分解之后就是将序列合并了。在调用堆栈的作用下,会将每个递归函数由下开始回溯。

在这里插入图片描述

归并排序的代码

void _MergeSort(int* a, int begin, int end,int* tmp)
{
	int mid = (begin + end) / 2;
	if (begin >= end)//不可再分,返回递归
	{
		return;
	}
	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid+1, end, tmp);


	int i = begin;

	//合并数组
	int begin1 = begin;//将原数组分为两部分,一部分是(begin,mid),另一部分是(mid+1,end)
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = end;

	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++];
	}

	memmove(a+begin, tmp+begin, sizeof(int) * (end-begin + 1));//将合并的数组拷贝到原数组
}
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);//创建一个相等元素个数的数组、
	_MergeSort(a, 0, n - 1, tmp);
	free(tmp);
}

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

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

相关文章

蓝桥杯 经验技巧篇

1. 注意事项 &#x1f468;‍&#x1f3eb; 官方通知 &#x1f468;‍&#x1f3eb; 资料文档 时间&#xff1a;4月13日 9:00~13:00 &#xff08;时长 4小时&#xff09;物品 准考证&#xff08;赛前一周开放下载&#xff0c;自行打印&#xff09;学生证身份证笔、水、外套&a…

DDIM,多样性与运行效率之间的trade off

DDPM的重大缺陷在于其在反向扩散的过程中需要逐步从 x t x_t xt​倒推到 x 0 x_0 x0​&#xff0c;因此其推理速度非常缓慢。相反&#xff0c;DDPM的训练过程是很快的&#xff0c;可以直接根据 x 0 x_0 x0​到 x t x_t xt​添加的高斯噪声 ϵ \epsilon ϵ完成一次训练。 为了解…

springboot整合ShardingSphere分库分表并插入1kw条记录

目录 一&#xff0c;数据分片 二&#xff0c;水平分片 三&#xff0c;创建数据库表 四&#xff0c;springboot项目导入依赖 五&#xff0c;创建类 六&#xff0c;bug bug放到最后了。 一&#xff0c;数据分片 数据分片指按照某个维度将存放在单一数据库中的数据分散地存…

(学习日记)2024.04.06:UCOSIII第三十四节:互斥量函数接口讲解

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

【Hadoop技术框架-MapReduce和Yarn的详细描述和部署】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;今天的内容主要是Hadoop的后两个组件&#xff1a;MapReduce和yarn的相关内容。同时还有Hadoop的完整流程。希望对大家有所帮助。感谢大家关注点赞。 &#x1f49e;&#x1f49e;前路漫漫&…

香港科技大学(广州)智能制造学域可持续能源与环境学域博士招生宣讲会——重庆大学专场(暨全额奖学金政策)

两个学域代表教授亲临现场&#xff0c;面对面答疑解惑助攻申请&#xff01;可带简历现场咨询和面试&#xff01; &#x1f4b0;一经录取&#xff0c;享全额奖学金1.5万/月&#xff01; 报名链接&#xff1a;https://www.wjx.top/vm/wmuN2ea.aspx# 地点&#xff1a;重庆大学A区…

观《你想活出怎样的人生》有感

《你想活出怎样的人生》 四月六号&#xff0c;和赵茜小美女观看了宫崎骏导演拍的《你想活出怎样的人生》&#xff0c;感受颇丰&#xff0c;特此写一篇文章以记之。 电影简介 《你想活出怎样的人生》是宫崎骏执导的动画电影&#xff0c;不仅是宫崎骏的复出之作&#xff0c;也…

ARP寻址过程

当知道目标的IP但是不知道目标的Mac地址的时候就需要借助ARP寻址获取目标的Mac地址&#xff0c;传输层借助四元组&#xff08;源IP源端口&#xff1a;目标IP目标端口&#xff09;匹配&#xff0c;网络层借助IP匹配&#xff0c;数据链路层则根据Mac地址匹配&#xff0c;数据传输…

77、WAF攻防——权限控制代码免杀异或运算变量覆盖混淆加密传参

文章目录 WAF规则webshell免杀变异 WAF规则 函数匹配 工具指纹 webshell免杀变异 php 传参带入 eval可以用assert来替换,assert也可以将字符串当作php代码执行漏洞 php 变量覆盖 php 加密 使用加密算法对php后门进行加密 php 异或运算 简化:无字符webshellP 无数字字母rc…

Open3D(C++) 鲁棒损失函数优化的ICP算法

目录 一、损失函数1、关于2、损失函数3、Open3D实现二、代码实现三、结果展示1、配准前1、配准后本文由CSDN点云侠原创,

11、子串-滑动窗口最大值

题解&#xff1a; 双端队列是一种特殊的队列&#xff0c;允许你在队列的两端进行插入和删除操作。在滑动窗口问题中&#xff0c;我们使用它来存储可能是当前窗口最大值的元素的索引。 维护队列的顺序&#xff1a; 当新元素进入窗口时&#xff0c;我们将它与队列尾部的元素进…

307k star, 免费的编程书籍 free-programming-books

307k star, 免费的编程书籍 free-programming-books 分类 开源分享 项目名: free-programming-books -- 各种编程语言免费学习资源 Github 开源地址&#xff1a; https://github.com/EbookFoundation/free-programming-books 查找页面&#xff08;英文&#xff09;&#xff…

在线代码生成器Mybaitis和Mybaitis Plus

功能 支持根据提供的数据信息自动找表和表字段可以单独生成某个文件可以按需生成多个文件(打包为 zip)常用的 vo 和 dto 支持字段自定义(支持多表字段合并)在非包的场景可以不输入 root 包支持批量多表生成支持 lombok 和 swaggerMybaitis和Mybaitis Plus 在页面样式上基本一样…

java流式计算Stream

java流式计算Stream 流(Stream)到底是什么呢? 是数据渠道&#xff0c;用于操作数据源&#xff08;集合、数组等&#xff09;所生成的元素序列。 “集合讲的是数据&#xff0c;流讲的是计算! ” 特点&#xff1a; Stream自己不会存储元素。 Stream不会改变源对象。相反&#x…

分享一份适合练手的软件测试实战项目

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

面试算法-152-螺旋矩阵

题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 解 class Solution {public List<Integ…

串口和 蓝牙模块HC08

串口基本认知 串行接口简称串口&#xff0c;也称 串行通信 接口或 串行通讯接口 &#xff08;通常指 COM 接口 &#xff09;&#xff0c;是采用串行通信方 式的 扩展接口 。串行 接口&#xff08;Serial Interface &#xff09;是指数据一位一位地顺序传送。其特点是 通信线路…

vulhub打靶记录——Corrosion2

文章目录 主机发现端口扫描ssh—22search openssh EXP web服务—8080目录扫描登录tomcat后台 提权切换用户查看用户权限寻找SUID命令破解登录密文 总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.151.0/24192.168.151.1&am…

【LeetCode】894. 所有可能的真二叉树

文章目录 [894. 所有可能的真二叉树](https://leetcode.cn/problems/all-possible-full-binary-trees/)思路一&#xff1a;分治代码&#xff1a;思路二&#xff1a;记忆化搜索代码&#xff1a; 894. 所有可能的真二叉树 思路一&#xff1a;分治 1.递归&#xff0c;n1 时&#…

数字图像处理——数字图像基础(持续更新)

视觉感知要素——亮度适应和鉴别&#xff1a; 人眼对不同亮度的适应和鉴别能力&#xff1a;亮 -> 暗 适应&#xff1b;暗 -> 亮 适应 图像取样和量化 1、概念&#xff1a; 数字化坐标值称为取样 数字化幅度值称为量化 2、 坐标的数字化称为采样&#xff0c;…