当前位置: 首页 > news >正文

排序 -- 手撕归并排序(递归和非递归写法)

一、基本思想

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

 二、归并排序的特性总结

1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(N)
4. 稳定性:稳定

三、归并排序

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

相关文章:

排序 -- 手撕归并排序(递归和非递归写法)

一、基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有…...

防火墙基础及登录(华为)

目录 防火墙概述防火墙发展进程包过滤防火墙代理防火墙状态检测防火墙UTM下一代防火墙&#xff08;NGFW&#xff09; 防火墙分类按物理特性划分软件防火墙硬件防火墙 按性能划分百兆级别和千兆级别 按防火墙结构划分单一主机防火墙路由集成式防火墙分布式防火墙 华为防火墙利用…...

【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 中&#xff0c;多态&#xff08;Polymorphism&#xff09;是指不同的对象可以对相同的消息&#xff08;方法调用&#xff09;做出不同的响应。 简单来说&#xff0c;多态允许使用一个统一的接口来操作不同类型的对象&#xff0c;而这些对象会根据自身的类型来执行相应…...

001uboot体验

1.uboot的作用&#xff1a; 上电->uboot启动->关闭看门狗、初始化时钟、sdram、uart等外设->把内核文件从flash读取到SDRAM->引导内核启动->挂载根文件系统->启动根文件系统的应用程序 2.uboot编译 uboot是一个通用的裸机程序&#xff0c;为了适应各种芯片&…...

Flask之电子邮件

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、使用Flask-Mail发送电子邮件 1.1、配置Flask-Mail 1.2、构建邮件数据 1.3、发送邮件 二、使用事务邮件服务SendGrid 2.1、注册SendGr…...

Vue 2 与 ECharts:结合使用实现动态数据可视化

在现代前端开发中&#xff0c;数据可视化变得越来越重要。ECharts 是一个强大的数据可视化库&#xff0c;而 Vue 2 则是一个流行的前端框架。本文将介绍如何将 Vue 2 和 ECharts 结合使用&#xff0c;以实现动态数据可视化。 安装与配置 首先&#xff0c;确保你的项目中已经安…...

.net core Redis 使用有序集合实现延迟队列

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的&#xf…...

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…...

鸿蒙系统:未来智能生态的引领者

在当今这个日新月异的互联网领域&#xff0c;操作系统作为连接硬件与软件的桥梁&#xff0c;其重要性不言而喻。随着华为鸿蒙系统&#xff08;HarmonyOS&#xff09;的崛起&#xff0c;一场关于操作系统未来的讨论再次被推向高潮。 鸿蒙OS&#xff0c;华为的全新力作&#xff…...

Java语言程序设计——篇二(1)

Java语言基础 数据类型关键字与标识符关键字标识符 常量与变量1、常量2、变量 类型转换自动类型转换强制类型转换 数据类型 数据的基本要素数据的性质&#xff08;数据结构&#xff09;数据的取值范围&#xff08;字节大小&#xff09;数据的存储方式参与的运算 Java是一门强类…...

水果商城系统 SpringBoot+Vue

1、技术栈 技术栈&#xff1a;SpringBootVueMybatis等使用环境&#xff1a;Windows10 谷歌浏览器开发环境&#xff1a;jdk1.8 Maven mysql Idea 数据库仅供学习参考 【已经答辩过的毕业设计】 项目源码地址 2、功能划分 3、效果演示...

半导体制造企业 文件共享存储应用

用户背景&#xff1a;半导体设备&#xff08;上海&#xff09;股份有限公司是一家以中国为基地、面向全球的微观加工高端设备公司&#xff0c;为集成电路和泛半导体行业提供具竞争力的高端设备和高质量的服务。 挑战&#xff1a;芯片的行业在国内迅猛发展&#xff0c;用户在上海…...

深入分析 Android BroadcastReceiver (九)

文章目录 深入分析 Android BroadcastReceiver (九)1. Android 广播机制的扩展应用与高级优化1.1 广播机制的扩展应用1.1.1 示例&#xff1a;有序广播1.1.2 示例&#xff1a;粘性广播1.1.3 示例&#xff1a;局部广播 1.2 广播机制的高级优化1.2.1 示例&#xff1a;使用 Pending…...

从数据到洞察:DataOps加速AI模型开发的秘密实践大公开!

作者 | 代立冬&#xff0c;白鲸开源科技联合创始人&CTO 引言 在AI驱动的商业世界中&#xff0c;DataOps作为连接数据与洞察的桥梁&#xff0c;正迅速成为企业数据战略的核心。 在WOT全球技术创新大会2024北京站&#xff0c;白鲸开源联合创始人&CTO 代立冬 在「大数据…...

全景图三维3D模型VR全景上传展示H5开发

全景图三维3D模型VR全景上传展示H5开发 3D互动体验平台的核心功能概览 兼容广泛格式&#xff1a;支持OBJ、FBX、GLTF等主流及前沿3D模型格式的无缝上传与展示&#xff0c;确保创意无界。 动态交互探索&#xff1a;用户可自由旋转、缩放、平移模型&#xff0c;深度挖掘每一处…...

前端面试题29(js闭包和主要用途)

JavaScript 中的闭包是一个非常强大的特性&#xff0c;它允许一个函数访问并操作其词法作用域之外的变量。闭包的形成主要依赖于函数的作用域链&#xff0c;即函数可以访问在其外部定义的变量&#xff0c;即使外部函数已经执行完毕。下面我会通过几个方面来帮助你理解闭包的概念…...

使用Keil 点亮LED灯 F103ZET6

1.新建项目 不截图了 2.startup_stm32f10x_hd.s Keil\Packs\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM 搜索startup_stm32f10x_hd.s 复制到项目路径&#xff0c;双击Source Group 1 3.项目文件夹新建stm32f10x.h&#xff0c; 新建文件main.c #include "stm32f10x…...

流批一体计算引擎-12-[Flink]旁路输出getSideOutput(OutputTag)实现拆分流和复制流

官网旁路输出 Flink拆分流和复制流 我们在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把流进行拆分或者复制。 如果是使用filter来进行拆分,也能满足我们的需求,但每次筛选都要保留整个流,然后遍历整个流,显然很浪费性能,假如能够在一个流了多次…...

【Scrapy】 Scrapy 爬虫框架

准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 &#x1f3b5; 陈慧娴《傻女》 Scrapy 是…...

D3KeyHelper:暗黑3玩家的智能按键助手,告别重复操作疲劳

D3KeyHelper&#xff1a;暗黑3玩家的智能按键助手&#xff0c;告别重复操作疲劳 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面&#xff0c;可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 你是否曾在《暗黑破坏…...

举一个具体例子说明为什么索引不是越多越好,举具体字段

文章目录1. 核心舞台&#xff1a;笔记表 (t_note) 结构设计&#x1f6a8; 错误的操作&#xff1a;2. 结合具体字段&#xff0c;拆解三大翻车现场现场一&#xff1a;给 view_count&#xff08;浏览量&#xff09;加索引 —— 导致写放大&#xff0c;拖垮数据库现场二&#xff1a…...

终极Node.js Mock工具:Mockery入门到精通实战教程

终极Node.js Mock工具&#xff1a;Mockery入门到精通实战教程 【免费下载链接】mockery Simplifying the use of mocks with Node.js 项目地址: https://gitcode.com/gh_mirrors/mock/mockery Mockery是Node.js生态中简化Mock使用的终极工具&#xff0c;它为开发者提供了…...

Claude SWOT分析(内部风控文档流出版):3类高危使用场景+2个监管红线预警

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Claude SWOT分析&#xff08;内部风控文档流出版&#xff09;&#xff1a;3类高危使用场景2个监管红线预警 高危使用场景识别 在企业级AI应用中&#xff0c;Claude模型若未经严格风控适配&#xff0c;…...

Atomic Layout核心概念解析:Composition组件如何实现布局与间距分离的终极指南

Atomic Layout核心概念解析&#xff1a;Composition组件如何实现布局与间距分离的终极指南 【免费下载链接】atomic-layout Build declarative, responsive layouts in React using CSS Grid. 项目地址: https://gitcode.com/gh_mirrors/at/atomic-layout Atomic Layout…...

TV Bro电视浏览器:为智能电视打造的最佳遥控器上网解决方案

TV Bro电视浏览器&#xff1a;为智能电视打造的最佳遥控器上网解决方案 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro 还在为智能电视上网操作不便而烦恼吗&#xff1f…...

学习日志(三)【php语法学习,iscc校赛wp】

1. 任务 1.1.1.1.1.1. 知识部分 rce看【之前的笔记&#xff1f;】php的知识点学习继续jwt token好像是比赛的题目考察内容&#xff0c;我看看php伪协议 1.1.1.1.1.2. 题目 参加iscc比赛【五一】rce题目 1.1.1.1.1.3. 环境配置 把vscode搞好&#xff0c;上学期没有把Php配…...

掌握Umi-OCR:5分钟上手开源免费离线文字识别工具

掌握Umi-OCR&#xff1a;5分钟上手开源免费离线文字识别工具 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生成二维码。内置多国语言库。…...

【RT-DETR实战】070、模型分析工具:PyTorch Profiler性能分析

上周在部署RT-DETR到边缘设备时遇到一个诡异现象:模型推理时延波动极大,有时30ms,偶尔突然跳到200ms。 盯着代码看了半天没发现逻辑问题,数据流也正常。这种时候,靠猜是没用的,必须上性能分析工具——PyTorch Profiler。 今天我们就来聊聊怎么用它揪出那些藏在细节里的…...

UE5 Cesium项目里,如何把默认的飞行Pawn换成建筑漫游Pawn?保姆级迁移教程

UE5 Cesium项目建筑漫游Pawn迁移实战&#xff1a;从飞行模式到精细化浏览的完整指南当你在UE5中结合Cesium插件构建数字孪生场景时&#xff0c;DynamicPawn提供的全球飞行体验令人印象深刻。但当视角聚焦到单体建筑或室内空间时&#xff0c;那种仿佛操控无人机般的操作方式就显…...