手把手教你归并排序(递归)

2023-10-27

今天,小编继续带大家学习排序算法,这次我们一起来学习归并排序的递归算法,多多点赞支持博主,速更非递归算法哦!

目录

一.实现原理

二.代码实现

三.注意事项与缺点 


 

一.实现原理

归并算法的实现与快排类似,都是采用了分治递归的思路。

它的时间复杂度也是O(n*logn)。

但不一样的是,快排是从排序最上层开始一点点递归到最底层;而归并是通过递归直接到最底层,从最底层开始一步步返回到最上层。

我们拿int类型的排序举例,归并来到最底层之后,应该是两个数字一组进行比较,从小到大排好,之后回到上一层,再这样排,直到到达最上层。

那有人会问了,这样子每一层都排好后返回上层不久又乱了,又要重新排了么。哎,这就要说我们归并排序的与众不同了。

以升序为例,归并是基于两个数组都是升序的基础上,记录两个指针分别指向两个数组的头,两指针所代表的数相比,小的顺次放入新数组,该指针指向下一个下标,循环这个比较的过程,直到其中一个指针指到尾,另一个数组全部放入新数组即可。

用图画来表示就是如下步骤:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCx6KaBIOWuheWcqOWutg==,size_20,color_FFFFFF,t_70,g_se,x_16

 

二.代码实现

void mergesort(int* a, int left,int right,int n);//归并排序

void _mergesort(int* a, int left, int right, int *tmp);//归并排序的子函数

void mergesort(int* a, int left,int right,int n)//归并排序
{
	int* tmp = (int*)malloc(sizeof(int) * n);//创建一个动态数组,存放归并后的有序数组
	_mergesort(a, left, right, tmp);
}

void _mergesort(int* a, int left, int right, int *tmp)//归并的子排序
{
	if (left >= right) return;//递归返回条件
	int mid = (left + right) >> 1;
	//分治递归思想
	_mergesort(a, left, mid, tmp);
	_mergesort(a, mid + 1, right, tmp);
	//归并
	int begin1 = left, begin2 = mid + 1,i_tmp=left;//注意要专门设一个变量存放tmp数组的下标
	while (begin1 <= mid && begin2 <= right)//归并继续条件
	{
		if (a[begin1] < a[begin2]) tmp[i_tmp++]= a[begin1++];
		else tmp[i_tmp++] = a[begin2++];
	}
	//归并结束后可能会有一个数组的数还未完全放入tmp中
	while (begin1 <= mid) tmp[i_tmp++] = a[begin1++];
	while (begin2 <= mid) tmp[i_tmp++] = a[begin2++];
	//将tmp数组中的数放入原数组(a)中
	for (int i = left; i <= right; i++)
	{
		a[i] = tmp[i];
	}
}

三.注意事项与缺点 

值得注意的是:我们需要一个子函数来进行递归,是因为归并算法要创建一个临时数组存放每次比较完的数,而因为是递归的方法,递归多少次就要创建多少个临时数组,势必会有内存的占用和浪费,因此,采用主归并函数来创建一次临时数组,子函数来接收这个临时数组,就能做到每次递归子函数时都是调用这一个临时数组了。

但是,之前快排的时候讲过,一旦递归调用次数过多,会导致栈溢出,那么如果归并也能采用非递归的算法,就会节省很多空间而且创建的临时数组也能直接在归并函数中使用,不用再创建子函数了。

因此,多多点赞支持博主,下一篇就会速更归并排序算法的非递归实现哦!


感谢点赞支持

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手把手教你归并排序(递归) 的相关文章

随机推荐

  • 【华为OD机试 】 单词搜索(C++ Java JavaScript Python)

    题目描述 找到它是一个小游戏 你需要在一个矩阵中找到给定的单词 假设给定单词 HELLOWORD 在矩阵中只要能找到 H gt E gt L gt L gt O gt W gt O gt R gt L gt D连成的单词 就算通过 注意区分
  • flask 写数据mysql_Flask从入门到精通之MySQL数据库操作

    前面的章节中我们已经学习了如何建立模型和关系 接下来我们学习如何使用模型的最好方法是在Python shell 中实际操作 并将介绍最常用的数据库操作 一 创建表 首先 我们要让Flask SQLAlchemy 根据模型类创建数据库 方法是
  • 27.EI文章复现《高比例清洁能源接入下计及需求响应的配电网重构》

    下载地址 高比例清洁能源接入下计及需求响应的配电网重构 1主要内容 该程序复现 高比例清洁能源接入下计及需求响应的配电网重构 以考虑网损成本 弃风弃光成本和开关操作惩罚成本的综合成本最小为目标 针对配电网重构模型的非凸性 引入中间变量并对其
  • Templates and Classes___CH_19

    19 1 Template classes Templates and container classes Template classes in the standard library Now that we ve covered te
  • 分库分表

    名词解释 库 database 表 table 分库分表 sharding 为什么要分库分表 移动互联网时代 海量的用户每天产生海量的数量 比如 用户表 订单表 交易流水表 以支付宝用户为例 8亿 微信用户更是10亿 订单表更夸张 比如美团
  • Python 20.opencv 直方图均衡化,CLAHE(对比度改变)

    import cv2 import numpy as np img cv2 imread pic1 png 0 进行直方图均衡化 equ cv2 equalizeHist img CLAHE有限对比适应性直方图均衡化 作用 限制对比度下降
  • 第一个项目单个交换机接入网络

    按图片上的要求来将一个交换机接入网络 配置明细路由 vlanif当网关
  • MATLAB中LSTM时序分类的用法与实战

    MATLAB中LSTM时序分类的用法与实战 说明 本教程适用于R2018b版本的matlab 不知道R2018a有没有 但是2017版本的肯定是没有LSTM工具箱的了 所以版本低的趁这个机会卸载然后重新下载安装吧 引用参考 1 matlab
  • 基于昇腾CANN的推理应用开发--语义分割(Python)

    前情提要 基于 Python 开发 通过网络模型加载 推理 结果输出的部署全流程展示 快速熟悉并掌握语义分割基本开发流程 目录 1 内容及目标 1 1 内容 1 2 目标 1 3 先导知识 2 理解原始模型 2 1 网络结构 2 2 查看模
  • stable diffusion model训练遇到的问题【No module named ‘triton‘】

    一天早晨过来 发现昨天还能跑的diffusion代码 突然出现了 No module named triton 的问题 导致本就不富裕的显存和优化速度雪上加霜 因此好好探究了解决方案 首先是原因 由于早晨过来发现 电脑重启 导致了 训练终止
  • 冒泡排序与选择排序区别

    冒泡排序 冒泡排序 BubbleSort 的基本概念是 依次比较相邻的两个数 将小数放在前面 大数放在后面 即在第一趟 首先比较第1个和第2个数 将小数放前 大数 放后 然后比较第2个数和第3个数 将小数放前 大数放后 如此继续 直至比较最
  • LeetCode 热门100题 2.两数相加

    public class Solution public ListNode addTwoNumbers ListNode l1 ListNode l2 int num1 ListToArray l1 int num2 ListToArray
  • 开源创作工具一览

    GIMP 2 8 http www gimp org 常见的位图编辑工具 不再赘述 新的 2 8 版本增加了单窗口模式 层分组等功能 Fedora 17 安装 pkcon install gimp MyPaint http mypaint
  • 简单的数据库关系表建立

    表与表之间一般存在三种关系 即一对一 一对多 多对多关系 下面分别就三种关系讲解数据库相关设计的思路和思考过程 1 一对一关系 例如 下面的一张表 保存了人的相关信息 有男有女 要求查处所有的夫妻 sql代码 CREATE TABLE IF
  • android上架备案公钥和md5获取工具

    最近很多公司上架遇到了一个问题 就是要提供app的备案证明 现在android上架都需要备案了 但是我们的证书都是通过工具生成的 哪里知道公钥和md5那些东西呢 无论安卓备案还是ios备案都需要提供公钥和md5 包括ios的备案也是 找了很
  • uni-app使用swiper实现tab左右滑动下拉无法触发onReachBottom页面生命周期

    注意要点 1 通过uni getSystemInfo获取设备具体高度 定义swiper的高度 将swiper撑开 2 利用scroll view视图容器的 scrolltolower属性实现触底加载 3 点击tab切换也会触发swiper的
  • MQTT 5.0 Reason Code 介绍与使用速查表

    Reason Code Reason Code 在 MQTT 中的主要作用是为客户端和服务端提供更详细的反馈 比如我们可以在 CONNACK 报文中将用户名或密码错误对应的 Reason Code 反馈给客户端 这样客户端就能够知道自己无法
  • 使用matplotlib和seaborn绘图的常用参数

    plt grid b True ls color 606060 设置网格线 b控制网格线 ls设置网格线的样式 plt tick params labelsize 20 轴数值大小 labelsize设置数值展示大小 plt ylabel
  • JeeSite 是什么、概述

    见JeeSite官网 http jeesite4 mydoc io 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到教程 总体概述 快速访问 JeeSite 官网地址 http jeesite c
  • 手把手教你归并排序(递归)

    今天 小编继续带大家学习排序算法 这次我们一起来学习归并排序的递归算法 多多点赞支持博主 速更非递归算法哦 目录 一 实现原理 二 代码实现 三 注意事项与缺点 一 实现原理 归并算法的实现与快排类似 都是采用了分治递归的思路 它的时间复杂