11.6 归并排序

目录

11.6   归并排序

11.6.1   算法流程

11.6.2   算法特性

11.6.3   链表排序


11.6   归并排序

归并排序(merge sort)是一种基于分治策略的排序算法,包含图 11-10 所示的“划分”和“合并”阶段。

  1. 划分阶段:通过递归不断地将数组从中点处分开,将长数组的排序问题转换为短数组的排序问题。
  2. 合并阶段:当子数组长度为 1 时终止划分,开始合并,持续地将左右两个较短的有序数组合并为一个较长的有序数组,直至结束。

归并排序的划分与合并阶段

图 11-10   归并排序的划分与合并阶段

11.6.1   算法流程

如图 11-11 所示,“划分阶段”从顶至底递归地将数组从中点切分为两个子数组。

  1. 计算数组中点 mid ,递归划分左子数组(区间 [left, mid] )和右子数组(区间 [mid + 1, right] )。
  2. 递归执行步骤 1. ,直至子数组区间长度为 1 时终止。

“合并阶段”从底至顶地将左子数组和右子数组合并为一个有序数组。需要注意的是,从长度为 1 的子数组开始合并,合并阶段中的每个子数组都是有序的。

merge_sort_step10

图 11-11   归并排序步骤

观察发现,归并排序与二叉树后序遍历的递归顺序是一致的。

  • 后序遍历:先递归左子树,再递归右子树,最后处理根节点。
  • 归并排序:先递归左子数组,再递归右子数组,最后处理合并。

归并排序的实现如以下代码所示。请注意,nums 的待合并区间为 [left, right] ,而 tmp 的对应区间为 [0, right - left] 。

merge_sort.c

/* 合并左子数组和右子数组 */
void merge(int *nums, int left, int mid, int right) {// 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]// 创建一个临时数组 tmp ,用于存放合并后的结果int tmpSize = right - left + 1;int *tmp = (int *)malloc(tmpSize * sizeof(int));// 初始化左子数组和右子数组的起始索引int i = left, j = mid + 1, k = 0;// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中while (i <= mid && j <= right) {if (nums[i] <= nums[j]) {tmp[k++] = nums[i++];} else {tmp[k++] = nums[j++];}}// 将左子数组和右子数组的剩余元素复制到临时数组中while (i <= mid) {tmp[k++] = nums[i++];}while (j <= right) {tmp[k++] = nums[j++];}// 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间for (k = 0; k < tmpSize; ++k) {nums[left + k] = tmp[k];}// 释放内存free(tmp);
}/* 归并排序 */
void mergeSort(int *nums, int left, int right) {// 终止条件if (left >= right)return; // 当子数组长度为 1 时终止递归// 划分阶段int mid = left + (right - left) / 2;    // 计算中点mergeSort(nums, left, mid);      // 递归左子数组mergeSort(nums, mid + 1, right); // 递归右子数组// 合并阶段merge(nums, left, mid, right);
}

11.6.2   算法特性

  • 时间复杂度为 𝑂(𝑛log⁡𝑛)、非自适应排序:划分产生高度为 log⁡𝑛 的递归树,每层合并的总操作数量为 𝑛 ,因此总体时间复杂度为 𝑂(𝑛log⁡𝑛) 。
  • 空间复杂度为 𝑂(𝑛)、非原地排序:递归深度为 log⁡𝑛 ,使用 𝑂(log⁡𝑛) 大小的栈帧空间。合并操作需要借助辅助数组实现,使用 𝑂(𝑛) 大小的额外空间。
  • 稳定排序:在合并过程中,相等元素的次序保持不变。

11.6.3   链表排序

对于链表,归并排序相较于其他排序算法具有显著优势,可以将链表排序任务的空间复杂度优化至 𝑂(1) 。

  • 划分阶段:可以使用“迭代”替代“递归”来实现链表划分工作,从而省去递归使用的栈帧空间。
  • 合并阶段:在链表中,节点增删操作仅需改变引用(指针)即可实现,因此合并阶段(将两个短有序链表合并为一个长有序链表)无须创建额外链表。

具体实现细节比较复杂,有兴趣的读者可以查阅相关资料进行学习。

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

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

相关文章

雷池WAF-动态防护新功能体验

雷池WAF 雷池WAF&#xff08;Web Application Firewall&#xff0c;网络应用防火墙&#xff09;是由长亭科技开发的一个网络安全产品&#xff0c;它专注于保护Web应用免受黑客攻击。 今天主要讲的是长亭雷池最近新出的功能&#xff1a;动态防护 安装 雷池WAF支持多种安装方式…

Activiti7 Maven笔记

通过maven完成BPMN的创建,定义流程,部署流程,完成流程等操作 代码整合创建maven项目添加log4j日志配置添加activiti配置文件创建数据库 activitijava类编写程序生成表如果代码运行,没有生成表,可能是没有读取到activiti的配置文件 Activiti数据表介绍类关系图工作流引擎创建默认…

禁止某个网段访问网络

禁用攻击 改成桥接模式 nmtui&#xff0c;改手动&#xff0c;清ip虚拟网络编辑器改成桥接模式. 安装arpspoof工具 先试着运行arpspoof如果不成功&#xff0c;更新源apt-get update接着运行arpspoof/apt install dsniff成功后&#xff0c;看arpspoof颜色是否是蓝色 禁止某个…

【视频转码】ZLMediaKit漏洞报告的问题

漏洞问题&#xff1a; 支持ss1 rc4密码套件(bar mitzvah) 漏洞级别&#xff1a; 中危 漏洞修复&#xff1a; 方法&#xff1a;避免使用RC4密码&#xff0c;参考代码如下&#xff1a; 修改文件位于&#xff1a;webrtc/DtlsTransport.cpp ret SSL_CTX_set_cipher_list(ssl…

Windows主机信息收集

一、内网环境分析 1、什么是内网渗透 内网渗透: ①在拿到webshell的时候&#xff0c;想办法获得系统信息拿到系统权限&#xff0c;进入到网络系统内部之后收集内部 网络的各种信息&#xff0c;获取内部网络有价值的人员、资产信息。 ②内网渗透的第一步&#xff0c;内网信…

嵌入式linux中线程编程实现详解

大家好,今天主要给大家分享一下,线程的使用,通过具体的实例代码来说明一个线程创建到退出到回收的基本流程,后半部分则会通过实例来说明如何能够控制好线程,从临界资源访问与线程的执行顺序控制上引出互斥锁、信号量的概念与使用方法。 第一:为什么要使用线程 场景分析:…

三.三Vue 实现的精彩动画效果

在 Vue 开发中&#xff0c;我们可以利用<transition>组件来打造各种令人惊艳的动画效果。下面来详细看看这些有趣的动画效果及其实现代码。 一、缩放类效果 zoom-in&#xff08;整体放大进入&#xff09; <template><div><button click"isShow ! …

[数据集][目标检测]电力工地场景下的人头检测数据集VOC+YOLO格式7035张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7035 标注数量(xml文件个数)&#xff1a;7035 标注数量(txt文件个数)&#xff1a;7035 标注…

Dockershim 与 Containerd:两种容器运行时的故事

在不断发展的容器化世界中&#xff0c;两个关键组件经常被混淆&#xff1a;Dockershim 和 containerd。虽然它们在管理容器方面都发挥着重要作用&#xff0c;但它们的用途却截然不同。本文深入探讨了它们的功能&#xff0c;深入探讨了 Dockershim 和 containerd 之间的区别。 揭…

SpringBoot——全局异常处理

目录 异常 项目总结 新建一个SpringBoot项目 pom.xml Result&#xff08;通用的响应结果类&#xff09; MyBusinessException自定义异常类 GlobalExceptionHandler全局异常处理类 ExceptionController控制器 SpringbootExceptionApplication启动类 参考文章&#xff1a…

对比投入高成本自研推广系统,直接采用SaaS更有效益

推广分销作为一种有效的市场拓展方式&#xff0c;被越来越多的企业所采纳。部分企业会选择投入资源自研一套推广分销系统&#xff0c;但是其实最后发现几年过去了&#xff0c;投入了大量成本&#xff0c;系统仍然是一地鸡毛&#xff0c;还在定义一些基本的属性。 自研推广系统…

Web前端三大主流框架:Angular、React与Vue.js的深入探讨

在快速发展的Web前端领域&#xff0c;选择一款合适的框架对于提升开发效率、保证代码质量以及实现项目目标具有至关重要的作用。在众多前端框架中&#xff0c;Angular、React和Vue.js以其独特的优势和广泛的应用场景&#xff0c;成为了市场上的三大主流框架。本文将深入剖析这三…

08-使用HappyPack提升Webpack构建速度

使用HappyPack提升Webpack构建速度 笔记分享 在前端开发中&#xff0c;Webpack 是一种非常流行的模块打包工具。然而&#xff0c;随着项目规模的扩大和复杂度的增加&#xff0c;Webpack 的构建速度可能会成为一个瓶颈。为了提升构建速度&#xff0c;我们可以使用一些工具和优化…

基于4G工业路由器的信息发布系统物联网应用方案

随着物联网技术的快速发展&#xff0c;智能信息发布系统已成为城市管理和信息传播的重要工具。而4G工业路由器作为连接信息发布终端与云平台的关键设备&#xff0c;其在提升信息发布效率方面发挥着至关重要的作用。为了提升智能信息发布系统的效率和智能化水平&#xff0c;智联…

【RPG Maker MV 仿新仙剑 战斗场景UI (十)】

RPG Maker MV 仿新仙剑 战斗场景UI &#xff08;十&#xff09; 前言角色站位人物站位人物影子 前言 上一期完成了几个功能&#xff0c;虽然没有进行进一步的优化&#xff0c;但基础的功能已经完成&#xff0c;现在记录下已完成及未完成的功能&#xff1a; 战斗菜单 一级战斗菜…

python opencv运行报错

报错如下错误&#xff1a;The function is not implemented. Rebuild the library with Windows, GTK 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvShowImage 解决办…

PromptIR论文阅读笔记

MZUAI和IIAI在NIPS2023上的一篇论文&#xff0c;用prompt来编码degradation&#xff0c;然后用来guide restoration network&#xff0c;使得模型能够泛化到不同degradation types and levels&#xff0c;也就是说是一个模型一次训练能够应对多种degradation的unified model。文…

讲座PPT分享|医学人工智能开始进入黄金时代|24年6月·讲座速递·06-03

小罗碎碎念 这期推文想分享的是自己四月底受邀做的一个报告——主题是“人工智能在肿瘤领域的进展&人工智能在脊柱外科领域中的进展”。 先解释一下&#xff0c;为什么我一个研究肿瘤的&#xff0c;会去关注脊柱外科——因为受到了脊柱外科医生的邀请&#xff0c;去给他们…

PTR记录-系统架构师(五)

1、关于串行总线的说法中&#xff0c;正确的是&#xff08;&#xff09;。 A串行总线一般都是双全工总线&#xff0c;适宜于长距离传输数据 B串行总线传输的波特率是总线初始化时预先定义好的&#xff0c;使用中不可改变 C串行总线是按位&#xff08;bit&#xff09;传输数据…

每日练习——牛客周赛 Round 45

小紫的总分 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行代码 #include<iostream> using namespace std; int main(){int a,b,c,d,e,sum;cin>>a>>b>>c>>d>>e;sumabcde;if(sum>100){ cout<<"YES";}else cout&…