数据结构——排序算法——归并排序

将两个有序数组合并为一个有序数组

在第二个列表向第一个列表逐个插入的过程中,由于第二个列表已经有序,所以后续插入的元素一定不会在前面插入的元素之前。在逐个插入的过程中,每次插入时,只需要从上次插入的位置开始,继续向后寻找插入位置即可。这样一来,我们最多只需要将两个有序数组遍历一次就可以完成合并。

vector<int> merge(vector<int> arr1, vector<int> arr2)
{vector<int> result;int index1 = 0, index2 = 0;while (index1 < arr1.size() && index2 < arr2.size()) {if (arr1[index1] <= arr2[index2]) {result[index1 + index2] = arr1[index1];index1++;}else {result[index1 + index2] = arr2[index2];index2++;}}// 将剩余数字补到结果数组之后while (index1 < arr1.size()) {result[index1 + index2] = arr1[index1];index1++;}while (index2 < arr2.size()) {result[index1 + index2] = arr2[index2];index2++;}return result;
}

将两个无序数组合并为一个有序数组

我们可以把数组不断地拆成两份,直到只剩下一个数字时,这一个数字组成的数组我们就可以认为它是有序的。然后通过上述合并有序列表的思路,将 1 个数字组成的有序数组合并成一个包含 2 个数字的有序数组,再将 2 个数字组成的有序数组合并成包含 4 个数字的有序数组…直到整个数组排序完成。

 void mergeSort(vector<int> arr) {if (arr.size() == 0) return;vector<int> result = mergeSort(arr, 0, arr.size() - 1);// 将结果拷贝到 arr 数组中for (int i = 0; i < result.size(); i++) {arr[i] = result[i];}
}// 对 arr 的 [start, end] 区间归并排序vector<int> mergeSort(vector<int> arr, int start, int end) {// 只剩下一个数字,停止拆分,返回单个数字组成的数组if (start == end) return vector<int>{arr[start]};int middle = (start + end) / 2;// 拆分左边区域vector<int> left = mergeSort(arr, start, middle);// 拆分右边区域vector<int> right = mergeSort(arr, middle + 1, end);// 合并左右区域return merge(left, right);
}

归并排序的优化:减少临时空间的开辟

为了减少在递归过程中不断开辟空间的问题,我们可以在归并排序之前,先开辟出一个临时空间,在递归过程中统一使用此空间进行归并即可。


// 将 result 的 [start, middle] 和 [middle + 1, end] 区间合并
void merge(vector<int> arr, int start, int end, vector<int> result) 
{int end1 = (start + end) / 2;int start2 = end1 + 1;// 用来遍历数组的指针int index1 = start;int index2 = start2;while (index1 <= end1 && index2 <= end) {if (arr[index1] <= arr[index2]) {result[index1 + index2 - start2] = arr[index1++];}else {result[index1 + index2 - start2] = arr[index2++];}}// 将剩余数字补到结果数组之后while (index1 <= end1) {result[index1 + index2 - start2] = arr[index1++];}while (index2 <= end) {result[index1 + index2 - start2] = arr[index2++];}// 将 result 操作区间的数字拷贝到 arr 数组中,以便下次比较while (start <= end) {arr[start] = result[start++];}
}void mergeSort(vector<int> arr) 
{if (arr.size() == 0) return;vector<int> result;mergeSort(arr, 0, arr.size() - 1, result);
}// 对 arr 的 [start, end] 区间归并排序
void mergeSort(vector<int> arr, int start, int end, vector<int> result)
{// 只剩下一个数字,停止拆分if (start == end) return;int middle = (start + end) / 2;// 拆分左边区域,并将归并排序的结果保存到 result 的 [start, middle] 区间mergeSort(arr, start, middle, result);// 拆分右边区域,并将归并排序的结果保存到 result 的 [middle + 1, end] 区间mergeSort(arr, middle + 1, end, result);// 合并左右区域到 result 的 [start, end] 区间merge(arr, start, end, result);
}

请添加图片描述

原地归并排序

实现一

// 将 arr 的 [start, middle] 和 [middle + 1, end] 区间合并
void merge(vector<int> arr, int start, int end) 
{int end1 = (start + end) / 2;int start2 = end1 + 1;// 用来遍历数组的指针int index1 = start;int index2 = start2;while (index1 <= end1 && index2 <= end) {if (arr[index1] <= arr[index2]) {index1++;}else {// 右边区域的这个数字比左边区域的数字小,于是它站了起来int value = arr[index2];int index = index2;// 前面的数字不断地后移while (index > index1) {arr[index] = arr[index - 1];index--;}// 这个数字坐到 index1 所在的位置上arr[index] = value;// 更新所有下标,使其前进一格index1++;index2++;end1++;}}
}// 对 arr 的 [start, end] 区间归并排序
void mergeSort(vector<int> arr, int start, int end)
{// 只剩下一个数字,停止拆分if (start == end) return;int middle = (start + end) / 2;// 拆分左边区域mergeSort(arr, start, middle);// 拆分右边区域mergeSort(arr, middle + 1, end);// 合并左右区域merge(arr, start, end);
}void mergeSort(vector<int> arr)
{if (arr.size() == 0) return;mergeSort(arr, 0, arr.size() - 1);
}

实现二


void exchange(vector<int> arr, int i, int j)
{int temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}// 将 arr 的 [start, middle] 和 [middle + 1, end] 区间合并
void merge(vector<int> arr, int start, int end)
{int end1 = (start + end) / 2;int start2 = end1 + 1;// 用来遍历数组的指针int index1 = start;while (index1 <= end1 && start2 <= end) {if (arr[index1] > arr[start2]) {// 将 index1 和 start2 下标的数字交换exchange(arr, index1, start2);if (start2 != end) {// 调整交换到 start2 上的这个数字的位置,使右边区域继续保持有序int value = arr[start2];int index = start2;// 右边区域比 arr[start2] 小的数字不断前移while (index < end && arr[index + 1] < value) {arr[index] = arr[index + 1];index++;}// 交换到右边区域的这个数字找到了自己合适的位置,坐下arr[index] = value;}}index1++;}
}// 对 arr 的 [start, end] 区间归并排序
void mergeSort(vector<int> arr, int start, int end)
{// 只剩下一个数字,停止拆分if (start == end) return;int middle = (start + end) / 2;// 拆分左边区域mergeSort(arr, start, middle);// 拆分右边区域mergeSort(arr, middle + 1, end);// 合并左右区域merge(arr, start, end);
}void mergeSort(vector<int> arr) {if (arr.size() == 0) return;mergeSort(arr, 0, arr.size() - 1);
}

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

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

相关文章

堆排序(堆的构造及代码实现)

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

亿发2023智能ERP生产系统解决方案实施,规范中大型企业生产精细化

随着制造水平的不断增强&#xff0c;传统工厂的管理方式已经不能满足现代制造的要求。为了确保公司战略目标的实现&#xff0c;中大型制造企业需要借助信息技术来强化对业务流程的管理&#xff0c;而生产制造ERP系统的实施已成为企业走向信息化的关键战略环节。 工厂信息化建设…

02. Springboot集成Flyway

目录 1、前言 2、什么是Flyway&#xff1f; 3、为什么要使用 Flyway&#xff1f; 4、简单示例 4.1、创建Spring Boot工程 4.2、添加Flyway依赖 4.3、Springboot添加Flyway配置 4.4、创建执行SQL脚本 4.5、启动测试 4.6、Flyway版本管理 5、SQL脚本文件命名规则 6、…

荣誉加冕!八方锦程再次荣获招聘与任用价值大奖

智享会ALL IN 2023 人力资源服务展汇聚了全国32个省市地区,21个行业的HR从业者、上下游客户,9月19-20日齐聚上海跨国采购会展中心,共同见证ALL IN 2023的盛大开幕! 作为人力资源行业的奋进者,八方锦程与智享会同行走过了几载春秋,始终致力于推进人力资源服务高质量发展。 在本…

面试题:HTTPS 是如何保证传输安全的?又被问了!

文章目录 1. HTTP 协议1.1 HTTP 协议介绍1.2 HTTP 中间人攻击1.3 防止中间人攻击 2. HTTPS 协议2.1 HTTPS 简介2.2 CA 认证体系 总结 1. HTTP 协议 在谈论 HTTPS 协议之前&#xff0c;先来回顾一下 HTTP 协议的概念。 1.1 HTTP 协议介绍 HTTP 协议是一种基于文本的传输协议&…

SpringBoot调用ChatGPT-API实现智能对话

目录 一、说明 二、代码 2.1、对话测试 2.2、单次对话 2.3、连续对话 2.4、AI绘画 一、说明 我们在登录chatgpt官网进行对话是不收费的&#xff0c;但需要魔法。在调用官网的API时&#xff0c;在代码层面上使用&#xff0c;通过API KEY进行对话是收费的&#xff0c;不过刚…

基于Java社区生鲜电商平台设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

网络爬虫-----爬虫的分类及原理

目录 爬虫的分类 1.通用网络爬虫&#xff1a;搜索引擎的爬虫 2.聚焦网络爬虫&#xff1a;针对特定网页的爬虫 3.增量式网络爬虫 4.深层网络爬虫 通用爬虫与聚焦爬虫的原理 通用爬虫&#xff1a; 聚焦爬虫&#xff1a; 爬虫的分类 网络爬虫按照系统结构和实现技术&#…

所有人别错过!云计算真的不错,前景钱途并存!

近年来&#xff0c;中国云计算产业发展迅猛&#xff0c;保持30%以上的年均增长率&#xff0c;成为全球增速最快的市场之一&#xff0c;云计算应用领域正向制造、政务、金融、医疗、教育等企业级市场延伸拓展。目前&#xff0c;云计算应用的普及促使开源技术广受关注&#xff0c…

Linux内核源码分析 (B.5)推演 slab 内存池的设计与实现

Linux内核源码分析 (B.5)推演 slab 内存池的设计与实现 文章目录 Linux内核源码分析 (B.5)推演 slab 内存池的设计与实现[toc] 1\. 前文回顾2\. 既然有了伙伴系统&#xff0c;为什么还需要 Slab ?3\. slab 对象池在内核中的应用场景4\. slab, slub, slob 傻傻分不清楚5\. 从一…

C语言的编译过程详解

当我们编译C程序时会发生什么&#xff1f;编译过程中的组件有哪些&#xff0c;编译执行过程是什么样的? 什么是编译 C语言的编译过程就是把我们可以理解的高级语言代码转换为计算机可以理解的机器代码的过程&#xff0c;其实就是一个翻译的过程。 …

低噪声 256 细分微步进电机驱动MS35774/MS35774A(汽车应用级别)

MS35774/MS35774A 是一款高精度、低噪声的两相步进 电机驱动芯片&#xff0c;芯片内置功率 MOSFET&#xff0c;长时间工作的平均电 流可以达到 1.4A&#xff0c;峰值电流 2A。芯片集成了过温保护、欠压 保护、过流保护、短地保护、短电源保护功能。 主要特点 ◼ 2 相步进电机…

揭秘期权卖方稳赚的方法策略!

期权的卖方&#xff08;也称为房东包租婆&#xff09;是指出售期权合约的人&#xff0c;其赚取的费用被称为期权权利金。也就是房租租金&#xff0c;作为卖方&#xff0c;您有义务在期限内按照合约规定的价格出售或购买标的资产&#xff0c;下文介绍期权卖方稳赚的方法策略有哪…

国外发达国家码农是真混得好么?

来看看花旗工作十多年的码农怎么说吧! 美国最大的论坛 Reddit&#xff0c;之前有一个热帖&#xff1a; 一个程序员说自己喝醉了&#xff0c;软件工程师已经当了10年&#xff0c;心里有 好多话想说&#xff0c;“我可能会后悔今天说了这些话。”他洋洋洒洒写了 一大堆&#xff…

Hive内置函数字典

写在前面&#xff1a;HQL同SQL有很多的类似语法&#xff0c;同学熟悉SQL后一般学习起来非常轻松&#xff0c;写一篇文章列举常用函数&#xff0c;方便查找和学习。 1. 执行模式 1.1 Batch Mode 批处理模式 当使用-e或-f选项运行$ HIVE_HOME / bin / hive时&#xff0c;它将以…

数据挖掘十大算法

参考&#xff1a; ICDM&#xff1a;数据挖掘十大算法

1、RocketMQ概述

第1章 RocketMQ概述 一、MQ概述 1、MQ简介 MQ&#xff0c;Message Queue&#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是一套提供了消息生 产、存储、消费全过程API的软件系统。消息即数据。一般消息的体量不会很大。 2、MQ用途 从网上…

AI文本创作在百度App发文的实践

作者 | 内容生态端团队 导读 大语言模型&#xff08;LLM&#xff09;指包含数百亿&#xff08;或更多&#xff09;参数的语言模型&#xff0c;这些模型通常在大规模数据集上进行训练&#xff0c;以提高其性能和泛化能力。在内容创作工具接入文心一言AI能力后&#xff0c;可以为…

无涯教程-JavaScript - SIGN函数

描述 SIGN功能确定数字的符号。该函数返回- 如果数字为正,则为1 如果数字为0,则零(0) -1,如果数字为负 语法 SIGN (number)争论 Argument描述Required/OptionalNumberAny real number.Required Notes 如果指定的数字未被识别为数字值,则SIGN返回#VALUE!错误。 适用性 …

阿里云通义千问向全社会开放,近期将开源更大参数规模大模型

9月13日&#xff0c;阿里云宣布通义千问大模型已首批通过备案&#xff0c;并正式向公众开放&#xff0c;广大用户可登录通义千问官网体验&#xff0c;企业用户可以通过阿里云调用通义千问API。 通义千问在技术创新和行业应用上均位居大模型行业前列。IDC最新的AI大模型评估报告…