热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

排序算法专题归并排序

归并排序是一种十分经典的冲破O(n2)时间复杂度的排序算法,该算法是基于分治的思想,讲解算法原理之前,先看一下下面这张图。图片来源&#x

  归并排序是一种十分经典的冲破O(n2)时间复杂度的排序算法,该算法是基于分治的思想,讲解算法原理之前,先看一下下面这张图。
在这里插入图片描述


  • 图片来源:【算法】排序算法之归并排序
      上图就是归并算法的一个简单示例。该算法就是每次将数组递归拆解为两部分,直到所有部分包含元素为1,之后递归的将各个部分进行归并。
  • 具体的算法步骤如下:
  • 1:递归拆解数组,直到每个区块包含元素数量为1
    2:归并数组,直到归并后的数组长度等于原数组长度
    3: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    4:设定两个指针,最初位置分别为两个已经排序序列的起始位置
    5:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    5:重复步骤 4直到某一指针达到序列尾
    7:将另一序列剩下的所有元素直接复制到合并序列尾
    8:重复步骤2-7

  从上述可以看出,该算法的实现是基于递归思想,但是所有的递归都可以转换成迭代,因此该算法有两个实现方式,递归和迭代。


  • 代码如下,以递归为例:
  • 如果单从原理原理上来直接写代码会比较复杂,我们可以将该算法拆解为两个部分,及分割和归并。分割是一个简单的递归,代码如下:

def mergeSort(nums):"""将输入数组递归拆分&#xff0c;直到长度为1时返回&#xff0c;对每一步返回的left,right进行顺序归并>>>mergeSort(3,38, 5, 44, 15, 36)>>>[3, 5, 15, 36, 38, 44]"""if len(nums) < 2:return numsmid &#61; len(nums)//2left, right &#61; nums[:mid], nums[mid:]return mergeHelp(mergeSort(left), mergeSort(right))

  • 其中mergeHelp是mergeSort的一个help方法&#xff0c;用于对拆分后的数组进行顺序归并。
  • 以[3,38, 5, 44, 15, 36]举个栗子&#xff0c;说一下递归过程&#xff1a;
  • 1&#xff1a;[3, 38, 5] [44, 15, 36]
    2&#xff1a;[3] [38, 5]
    3&#xff1a;[38] [5]
    4&#xff1a;[44] [15, 36]
    5&#xff1a;[15] [36]

  • 接下来我们实现mergeHelp方法&#xff0c;就是给定两个有序数组&#xff0c;将其按顺序合并为一个数组&#xff0c;代码如下&#xff1a;

def mergeHelp(left, right):"""归并排序的help方法&#xff0c;用于将拆分的left和right进行顺序归并>>>mergeHelp([1, 3, 5], [2, 4, 5]):>>>[1, 2, 3, 4, 5, 5]"""res &#61; []while left and right:if left[0] <&#61; right[0]:res.append(left.pop(0))else:res.append(right.pop(0))while left:res.append(left.pop(0))while right:res.append(right.pop(0))return res

  • 当我们实现了这个方法之后&#xff0c;看一下分割&#43;归并的过程
  • [3, 38, 5] [44, 15, 36]  第一次分割
    左数组[3, 38, 5]部分&#xff1a;
    [3] [38, 5]  第一次分割
    [38] [5]  第二次分割&#xff08;左数组分割完毕&#xff0c;所有部分元素均为1&#xff09;
    [5, 38]  第一次归并
    [3, 5, 38]emsp; 第二次归并&#xff0c;完成[3, 38, 5]部分序列的排序
    右数组[44, 15, 36]部分&#xff1a;
    [44] [15, 36]  第一次分割
    [15] [36]  第二次分割
    [15, 36]  第一次合并
    [15, 36, 44]  第二次合并
    原数组的所有子序列完成排序&#xff0c;进行最终的合并
    [3, 5, 15, 36, 38, 44]  排序完成

  • 算法解析&#xff1a;算法的时间复杂度从两个部分分来来看&#xff0c;很明显在mergeSort()递归方法里面&#xff0c;迭代公式为mid &#61; len(nums)//2&#xff0c;该方法的时间复杂度是O(log n)&#xff0c;而在mergeHelp()归并方法里面&#xff0c;每一步像res里面追加一下元素&#xff0c;最终的的运行次数为len(left)&#43;len(right)&#xff0c;很明显时间复杂度为O(n)&#xff0c;因此归并排序算法的总时间复杂度为O(n log n)。由于算法运行过程中&#xff0c;会递归生成原数组的切片&#xff0c;切片总长度为n&#xff0c;所以归并排序算法的空间复杂度为O(n)。
  • 注意到我们在进行归并操作是&#xff0c;使用的是如下代码

while left and right:if left[0] <&#61; right[0]:res.append(left.pop(0))else:res.append(right.pop(0))

  • 也就是说对于同样大小的元素&#xff0c;我们先插入位于左边的&#xff0c;而后插入右边的&#xff0c;因此归并排序不会改变相同元素的相对位置&#xff0c;因此该算法是稳定的。

推荐阅读
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 计算成像的原理与应用研究
    本文探讨了计算成像的原理与应用研究。首先介绍了小孔成像实验和软件方面的相关内容。随后从傅里叶光学的角度简单谈了成像的过程。成像是观测样品分布的一种方法,通过成像系统接收光的强度来呈现图像。视网膜作为接收端接收到的图像实际上是由像元组成的矩阵,每个元素代表相应位置像元接收光的强度。大脑通过对图像的分析,得出一系列信息,如识别物体、判断距离等。计算成像是一种采集记录系统,通过处理数据得到样品分布与像的对应关系,用于后续问题的分析。 ... [详细]
author-avatar
天若无雨666
这个菇凉很宅,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有