排序 -- 手撕归并排序(递归和非递归写法)
一、基本思想


二、归并排序的特性总结
三、归并排序
1、递归实现
1.1 实现思想
使用递归方法来实现归并排序,这其中不止包含了递归这个思想,还使用了分治的理念。
其原理就是把待排序数组分成两个子序列,再分别把两个子序列分成其对应的子序列,直到每个子序列都只有唯一的一个数据时就停止递归。然后分别对子序列进行排序,最后将排序好的子序列合并起来。
一个小tip:就是归并排序归并数据的过程中我们需要额外开辟一个空间来存放中间数据,如果在原数组中进行归并的话会造成数据的覆盖或者导致数据错乱!!!
1.2 具体实现
// 时间复杂度O(N*logN) 空间复杂度:O(N)
void _MergeSort(int* a, int* tmp, int begin, int end)
{if (end <= begin){return;}int mid = (begin + end) / 2;// [begin, mid][mid+1, end]_MergeSort(a, tmp, begin, mid);_MergeSort(a, tmp, mid + 1, end);// 归并到tmp数据组,再拷贝回去// a->[begin, mid][mid+1, end]->tmpint begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;//尾插tmp数组下标int index = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}//拷贝回原数组memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int)); //+begin是因为归并的数组下标不一定从0开始
}//归并排序
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int)*n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, tmp, 0, n - 1);free(tmp);
}
2、 非递归实现
2.1 实现思想
相较于递归实现,非递归实现采用与希尔排序相似的方法。就是使用gap来确定归并区间并进行归并。

2.2 具体实现
//非递归--归并排序(防止下标越界)
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("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;}// [begin1,end1] [begin2,end2] 归并int index = i;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}// 拷贝回原数组memcpy(a + i, tmp + i, (end2 - i) * sizeof(int));}gap *= 2;}free(tmp);
}
2.3 关于非递归实现归并排序的一些细节
在我们要用非递归来实现归并排序时需要注意的是用gap来确定归并区间的界限会不会造成数组越界的问题。
上面这张图是我们用gap来区分归并的区间,这种方法有可能会造成第二个数组全部越界或者第二个数组的end越界。但我们要注意的是第一个数组的开头begin1永远不可能越界,因为begin1 == i,而循环条件中 i < n。
如下图所示:
所以我们就只需要加两个判定条件即可
1、判断begin2是否 >= 数组长度n,如果大于等于就直接跳出循环不用再进行归并
2、判断end2是否 >= 数组长度n,如果大于等于就修正end2,使其 == 数组结束位置 n - 1
相关文章:
排序 -- 手撕归并排序(递归和非递归写法)
一、基本思想 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有…...
防火墙基础及登录(华为)
目录 防火墙概述防火墙发展进程包过滤防火墙代理防火墙状态检测防火墙UTM下一代防火墙(NGFW) 防火墙分类按物理特性划分软件防火墙硬件防火墙 按性能划分百兆级别和千兆级别 按防火墙结构划分单一主机防火墙路由集成式防火墙分布式防火墙 华为防火墙利用…...
【Vue】使用html、css实现鱼骨组件
文章目录 预览图组件测试案例 预览图 组件 <template><div class"context"><div class"top"><div class"label-context"><div class"label" v-for"(item, index) in value" :key"index&qu…...
Python的多态
在 Python 中,多态(Polymorphism)是指不同的对象可以对相同的消息(方法调用)做出不同的响应。 简单来说,多态允许使用一个统一的接口来操作不同类型的对象,而这些对象会根据自身的类型来执行相应…...
001uboot体验
1.uboot的作用: 上电->uboot启动->关闭看门狗、初始化时钟、sdram、uart等外设->把内核文件从flash读取到SDRAM->引导内核启动->挂载根文件系统->启动根文件系统的应用程序 2.uboot编译 uboot是一个通用的裸机程序,为了适应各种芯片&…...
Flask之电子邮件
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、使用Flask-Mail发送电子邮件 1.1、配置Flask-Mail 1.2、构建邮件数据 1.3、发送邮件 二、使用事务邮件服务SendGrid 2.1、注册SendGr…...
Vue 2 与 ECharts:结合使用实现动态数据可视化
在现代前端开发中,数据可视化变得越来越重要。ECharts 是一个强大的数据可视化库,而 Vue 2 则是一个流行的前端框架。本文将介绍如何将 Vue 2 和 ECharts 结合使用,以实现动态数据可视化。 安装与配置 首先,确保你的项目中已经安…...
.net core Redis 使用有序集合实现延迟队列
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的…...
linux 安装Openjdk1.8
一、在线安装 1、更新软件包 sudo apt-get update 2、安装openjdk sudo apt-get install openjdk-8-jdk 3、配置openjdk1.8 openjdk默认会安装在/usr/lib/jvm/java-8-openjdk-amd64 vim ~/.bashrc export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export JRE_HOME${J…...
鸿蒙系统:未来智能生态的引领者
在当今这个日新月异的互联网领域,操作系统作为连接硬件与软件的桥梁,其重要性不言而喻。随着华为鸿蒙系统(HarmonyOS)的崛起,一场关于操作系统未来的讨论再次被推向高潮。 鸿蒙OS,华为的全新力作ÿ…...
Java语言程序设计——篇二(1)
Java语言基础 数据类型关键字与标识符关键字标识符 常量与变量1、常量2、变量 类型转换自动类型转换强制类型转换 数据类型 数据的基本要素数据的性质(数据结构)数据的取值范围(字节大小)数据的存储方式参与的运算 Java是一门强类…...
水果商城系统 SpringBoot+Vue
1、技术栈 技术栈:SpringBootVueMybatis等使用环境:Windows10 谷歌浏览器开发环境:jdk1.8 Maven mysql Idea 数据库仅供学习参考 【已经答辩过的毕业设计】 项目源码地址 2、功能划分 3、效果演示...
半导体制造企业 文件共享存储应用
用户背景:半导体设备(上海)股份有限公司是一家以中国为基地、面向全球的微观加工高端设备公司,为集成电路和泛半导体行业提供具竞争力的高端设备和高质量的服务。 挑战:芯片的行业在国内迅猛发展,用户在上海…...
深入分析 Android BroadcastReceiver (九)
文章目录 深入分析 Android BroadcastReceiver (九)1. Android 广播机制的扩展应用与高级优化1.1 广播机制的扩展应用1.1.1 示例:有序广播1.1.2 示例:粘性广播1.1.3 示例:局部广播 1.2 广播机制的高级优化1.2.1 示例:使用 Pending…...
从数据到洞察:DataOps加速AI模型开发的秘密实践大公开!
作者 | 代立冬,白鲸开源科技联合创始人&CTO 引言 在AI驱动的商业世界中,DataOps作为连接数据与洞察的桥梁,正迅速成为企业数据战略的核心。 在WOT全球技术创新大会2024北京站,白鲸开源联合创始人&CTO 代立冬 在「大数据…...
全景图三维3D模型VR全景上传展示H5开发
全景图三维3D模型VR全景上传展示H5开发 3D互动体验平台的核心功能概览 兼容广泛格式:支持OBJ、FBX、GLTF等主流及前沿3D模型格式的无缝上传与展示,确保创意无界。 动态交互探索:用户可自由旋转、缩放、平移模型,深度挖掘每一处…...
前端面试题29(js闭包和主要用途)
JavaScript 中的闭包是一个非常强大的特性,它允许一个函数访问并操作其词法作用域之外的变量。闭包的形成主要依赖于函数的作用域链,即函数可以访问在其外部定义的变量,即使外部函数已经执行完毕。下面我会通过几个方面来帮助你理解闭包的概念…...
使用Keil 点亮LED灯 F103ZET6
1.新建项目 不截图了 2.startup_stm32f10x_hd.s Keil\Packs\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM 搜索startup_stm32f10x_hd.s 复制到项目路径,双击Source Group 1 3.项目文件夹新建stm32f10x.h, 新建文件main.c #include "stm32f10x…...
流批一体计算引擎-12-[Flink]旁路输出getSideOutput(OutputTag)实现拆分流和复制流
官网旁路输出 Flink拆分流和复制流 我们在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把流进行拆分或者复制。 如果是使用filter来进行拆分,也能满足我们的需求,但每次筛选都要保留整个流,然后遍历整个流,显然很浪费性能,假如能够在一个流了多次…...
【Scrapy】 Scrapy 爬虫框架
准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 🎵 陈慧娴《傻女》 Scrapy 是…...
CDN 无法播放音视频?流媒体回源与 Range 配置修复
流媒体应用现在越来越普及,CDN(内容分发网络)早已成为音视频流畅播放的核心支撑——靠边缘节点就近分发,既能降低延迟,又能减轻源站压力,让用户不用长时间等待就能看高清内容。但实际运维中,“C…...
Beyond Compare许可证获取与激活全攻略
1. Beyond Compare简介与许可证类型解析 Beyond Compare作为一款老牌文件对比工具,已经陪伴开发者走过了20多个年头。我第一次接触它是在2015年做代码合并时,当时就被它直观的三栏式对比界面惊艳到了——左右两侧显示对比内容,中间实时标注差…...
无代码自动化:OpenClaw+Qwen3.5-9B可视化流程搭建
无代码自动化:OpenClawQwen3.5-9B可视化流程搭建 1. 为什么选择OpenClawQwen3.5-9B组合 去年夏天,我发现自己每周要花3小时重复做三件事:整理会议录音、提取待办事项、设置日历提醒。当我尝试用传统自动化工具时,要么需要写代码…...
Java程序员的云原生时代生存指南:面向软件测试从业者的专业视角
在技术浪潮的冲击下,云原生已从概念演进为产业标准。对于广大Java程序员而言,这既是挑战也是机遇。传统的技术栈和开发模式正在经历深刻变革,而软件测试作为保障质量的关键环节,其理念与实践也随之迭代。 一、 挑战审视ÿ…...
探索偏心轮飞剪的 Codesys 程序奥秘:基于偏心轮加滑块机构
偏心轮 飞剪 电子凸轮 codesys程序源码 适用于偏心轮加滑块机构 在自动化控制领域,偏心轮飞剪系统凭借其独特的运动特性和高效的切割能力,在众多生产场景中发挥着关键作用。今天咱们就深入探讨基于偏心轮加滑块机构的偏心轮飞剪的 Codesys 程序源码&…...
在CentOS上部署RustDesk私有中继服务器:从零搭建到安全配置
1. 环境准备:搭建RustDesk私有中继服务器的基石 在CentOS系统上部署RustDesk私有中继服务器,首先需要确保基础环境配置正确。我遇到过不少因为环境问题导致的部署失败案例,所以这部分我会详细说明每个环节的注意事项。 1.1 系统更新与基础依赖…...
ubuntu秘钥生成PKCS1 格式秘钥
openssl genrsa -out key 2048 openssl rsa -in key -out key2 -traditional...
美的集团2025年营收创新高、利润100%分红 落地1.3万个AI智能体
3月30日,美的集团发布2025年年报,实现营业总收入4585亿元,同比增长12.1%;归属于上市公司股东的净利润439.5亿元,同比上升14%。在业绩再创新高的同时,伴随我国“人工智能”行动的全面实施,美的集…...
解决Python ssl模块与系统OpenSSL版本不一致的编译指南
1. 为什么Python的ssl模块会与系统OpenSSL版本不一致? 很多开发者都遇到过这样的困惑:明明系统已经升级了OpenSSL,为什么Python的ssl模块还在使用旧版本?这个问题其实源于Python的编译机制。Python在编译安装时,会将当…...
终极指南:如何用res-downloader一键下载全网无水印资源
终极指南:如何用res-downloader一键下载全网无水印资源 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你是否经常…...


