C++归并排序

1 算法核心思想

归并排序是一种高效的排序方式,需要用到递归来实现,我们先来看一下动图演示:

算法核心思想如下:

1.将数组尽量平均分成两段。

2.将这两段都变得有序(使用递归实现)。

3.将两段合并。

2 代码实现

首先,我们先定义一个归并排序的函数,里面接受三个参数:

void MergeSort(int arr[], int left, int right) {}

arr代表需要进行排序的数组,left表示数组arr的最左端点,right表示数组arr的最右端点。

首先我们需要把数组分成两段,我们可以用二分的方法:

int mid = (left + right) >> 1;

这里右移(>>为右移运算符)1为和除以2含义相同。

也可以用防溢出,因为left+right的值可能会爆int,导致结果错误:

int mid = left + (right - left) >> 1;

然后对两段分别进行递归,第一段是[1, mid],第二段是[mid+1, right]:

MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, right);

由于我们需要对数组进行操作,但是直接在arr操作可能会导致原始数据丢失,但是如果再创建一个数组会占用内存,所以我们可以向电脑“租借”right-left+1个空间,用关键字new来完成:

int* tmp = new int[right - left + 1];

注意要以指针的形式定义。

由于我们要把数组变得有序,而我们归并排序的思想就是分而治之,然后再依次变得有序,需要用到分治的思想。那么我们先定义一些变量:

int cur = 0, cur1 = left, cur2 = mid + 1;

cur为tmp数组的元素下标,cur1为第一段的最左端点,cur2为第二段的最左端点。

然后我们对tmp数组和arr数组进行循环操作,这里可以用while循环,循环条件是cur1<=mid&&cur2<=right。

如果arr[cur1]比arr[cur2]更大,那么就先把arr[cur2]放回tmp,否则放arr[cur1]。

代码:

while(cur1 <= mid && cur2 <= right)
{if(arr[cur1] < arr[cur2])tmp[cur++] = arr[cur1++];elsetmp[cur++] = arr[cur2++];
}

然后处理可能有的数组残余未处理的部分:

while(cur1 <= mid)tmp[cur++] = arr[cur1++];
while(cur2 <= right)tmp[cur++] = arr[cur2++];

然后合并数组,方法跟处理时差不多的:

for(int i = 0; i < right - left + 1; i++)arr[left + i] = tmp[i];

就是把tmp的元素依次赋值给arr。

最有我们需要把tmp的空间还给内存,所以我们delete一下:

delete[] tmp;

然后我们的arr就变的有序了。

但是,如果这样写,程序就成功被我们干崩了,因为我们忘记写递归出口了,补一个递归出口:

if(left == right)return;

我们合并一下整段代码:

void MergeSort(int arr[], int left, int right) {if(left == right)return;int mid = (left + right) >> 1;MergeSort(arr, left, mid);MergeSort(arr, mid + 1, right);int* tmp = new int[right - left + 1];int cur = 0, cur1 = left, cur2 = mid + 1;while(cur1 <= mid && cur2 <= right){if(arr[cur1] < arr[cur2])tmp[cur++] = arr[cur1++];elsetmp[cur++] = arr[cur2++];}while(cur1 <= mid)tmp[cur++] = arr[cur1++];while(cur2 <= right)tmp[cur++] = arr[cur2++];for(int i = 0; i < right - left + 1; i++)arr[left + i] = tmp[i];delete[] tmp;
}

3 算法时间复杂度

正常情况下,归并排序时间复杂度为:

O(NLogN)

再见!

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

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

相关文章

机器学习算法篇(四)决策树算法

目录 一、决策树概述 1.1 概述 1.2 基本数学原理 二、熵原理形象解读与计算 2.1 熵的概念 2.2 熵的计算示例 2.3 条件熵 三、决策树构造实例 3.1 数据集示例 3.2 计算信息增益 3.3 递归构建决策树 四、信息增益和信息增益率 4.1 信息增益的缺陷 4.2 信息增益率 4…

React 状态管理入门:从 useState 到复杂状态逻辑

作为前端新手&#xff0c;在学习 React 时&#xff0c;useState 往往是我们接触的第一个 Hook。很多人最初会觉得它只能处理简单的计数器之类的状态&#xff0c;但实际上&#xff0c;useState 配合其他 Hook&#xff08;尤其是 useEffect&#xff09;可以轻松管理各种复杂状态。…

DirectX 修复工具检测 C++ 异常的七大解决方法

在使用电脑的过程中&#xff0c;尤其是在进行与图形处理、游戏运行或多媒体应用相关的操作时&#xff0c;我们可能会用到 DirectX 修复工具。然而&#xff0c;有时这个工具在运行时会检测到 C 异常&#xff0c;这无疑给我们带来了困扰。那么&#xff0c;当遇到这种情况时&#…

0.2. RAII原则:嵌入式C++的基石 (Resource Acquisition Is Initialization)

在C语言的世界里&#xff0c;我们背负着一项沉重而危险的职责&#xff1a;手动管理所有资源。无论是 malloc 后的 free&#xff0c;fopen 后的 fclose&#xff0c;还是获取互斥锁后的释放&#xff0c;程序员都必须在代码的每一个可能的退出路径上&#xff0c;确保资源被正确释放…

Uniworld-V1、X-Omni论文解读

目录 一、Uniworld-V1 1、概述 2、架构 3、训练过程 4、实验 二、X-Omni 1、概述 2、方法 一、Uniworld-V1 1、概述 动机&#xff1a;当前统一模型虽然可以实现图文理解和文本生成任务&#xff0c;但是难以实现图像感知&#xff08;检测/分割&#xff09;与图像操控&am…

安全常见漏洞

一、OWASP Top 101.注入漏洞(1)SQL 注入原理&#xff1a;通过用户输入注入恶意SQL代码示例&#xff1a;sql-- 恶意输入OR 11 -- 可能被注入的SQL SELECT * FROM users WHERE username OR 11 AND password (2)防护措施&#xff1a;使用参数化查询使用ORM框架实施最小权限原则…

管网遥测终端机——管网安全与效率的守护者

管网遥测终端机是一款智能化的管网监测与管理设备&#xff0c;它采用先进的物联网技术和自动化控制技术&#xff0c;能够全天候不间断地对管网系统进行实时监测。该设备通过集成高精度传感器、稳定可靠的通信模块和强大的数据处理单元&#xff0c;构建了一套完整的管网运行数据…

AIIData商业版v1.4.1版本发布会

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨杭州奥零数据科技官网&#xff…

【Layui】调整 Layui 整体样式大小的方法

Layui 的默认样式确实偏大,但你可以通过以下几种方法来调整整体大小: 使用缩放方法(最简单) 在 HTML 的 中添加以下 CSS: <style> html {font-size: 14px; /* 调整基础字体大小 */transform: scale(

MySQL连接数调优实战:查看与配置

MySQL HikariCP 连接数调优实战&#xff1a;如何查看用量 & 合理配置 max_connections 在做 Java 后端开发时&#xff0c;我们经常会遇到 MySQL 连接数配置问题&#xff0c;比如&#xff1a; max_connections 配多少合适&#xff1f;HikariCP 的 maximum-pool-size 要不要…

周志华院士西瓜书实战(一)线性规划+多项式回归+逻辑回归+决策树

目录 1. 线性规划 2. 多项式回归 3. 逻辑回归手写数字 4. Pytorch MNIST 5. 决策树 1. 线性规划 先生成 Y1.5X0.2ε 的&#xff08;X,Y&#xff09;训练数据 两个长度为30 import numpy as np import matplotlib.pyplot as plt def true_fun(X): # 这是我们设定的真实…

端到端供应链优化案例研究:需求预测 + 库存优化(十二)

本篇文章聚焦于供应链中的库存优化&#xff0c;技术亮点在于通过机器学习改进预测精度&#xff0c;成功将预测误差降低25%&#xff0c;并在六个月内实现库存过剩减少40%。该方法适用于需要优化库存和提升服务水平的商业场景&#xff0c;特别是制药行业&#xff0c;帮助企业在降…

Harbor 企业级实战:单机快速上手 × 高可用架构搭建 × HTTPS安全加固

文章目录一、建立项目二、命令行登录harbor&#xff08;配置在客户端即可&#xff09;三、给本地镜像打标签并上传到harbor四、下载harbor的镜像五、创建自动打标签上传镜像脚本六、修改harbor配置七、实现harbor高可用7.1 安装第二台harbor主机7.2 新建目标&#xff0c;输入第…

进程管理、系统高负载、cpu超过800%等实战问题处理

进程管理与高负载实战&#xff1a;CPU 飙到 800% 时的分析与处理 在生产环境中&#xff0c;系统高负载和 CPU 异常占用是运维工程师最常面对的场景之一。 这篇文章将从进程管理基础讲起&#xff0c;到高负载问题定位&#xff0c;再到CPU 占用 800% 的实战处理&#xff0c;帮助你…

控制建模matlab练习12:线性状态反馈控制器-①系统建模

此练习&#xff0c;主要是使用状态空间方程来设计控制器的方法和思路&#xff1a; ①系统建模&#xff1b; ②系统的能控性&#xff1b; ③极点配置&#xff1b; ④最优化控制LQR&#xff1b; ⑤轨迹追踪&#xff1b; 以下是&#xff0c;第①部分&#xff1a;系统建模&#xff…

bytearray和bytes

bytearray和bytes不一样的地方在于&#xff0c;bytearray是可变的。 str 人生苦短&#xff0c;我用Python! bytes bytearray(str.encode()) bytes bytearray(b\xe4\xba\xba\xe7\x94\x9f\xe8\x8b\xa6\xe7\x9f\xad\xef\xbc\x8c\xe6\x88\x91\xe7\x94\xa8Python!) str bytes.d…

护网行动之后:容器安全如何升级?微隔离打造内网“微堡垒”

护网行动刚刚落下帷幕&#xff0c;但这场没有硝烟的攻防演练&#xff0c;留给安全行业的思考却从未停止。当“横向移动”成为攻击方屡试不爽的杀手锏时&#xff0c;一个过去可能被忽视的角落——容器网络安全&#xff0c;在本届护网中被推到了前所未有的高度。面对云原生时代容…

一动鼠标就锁屏,设备活动监控方案的技术实现与应用

摘要&#xff1a;本文探讨基于本地化监控机制实现设备操作追踪的技术方案&#xff0c;重点解析其触发逻辑与隐私保护机制。方案适用于需要监控设备使用场景的技术人员。一、核心功能实现原理触发监控机制键盘钩子&#xff1a;通过系统级键盘事件监听&#xff08;AltL组合键激活…

从零开始学习:深度学习(基础入门版)(1天)

&#xff08;一&#xff09; opencv和opencv-contrib的安装&#xff08;1.1&#xff09;在桌面地底部的搜索栏&#xff0c;搜索命令提示符&#xff0c;点击并打开命令提示符&#xff08;1.2&#xff09;依次输入命令并按回车&#xff1a;pip install opencv-python3.4.18.65 -i…

SimpleMindMap:一个强大的Web思维导图

在信息爆炸的时代&#xff0c;如何高效地组织、记忆和表达复杂信息成为一项关键技能。思维导图作为一种强大的可视化工具&#xff0c;能够帮助我们理清思路、激发创意并提高学习效率。最近在逛github的时候发现了一个开源的思维导图工具SimpleMindMap&#xff0c;和家人们分享下…