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

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

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

  • 代码如下,以递归为例:
  • 如果单从原理原理上来直接写代码会比较复杂,我们可以将该算法拆解为两个部分,及分割和归并。分割是一个简单的递归,代码如下:
def mergeSort(nums):"""将输入数组递归拆分,直到长度为1时返回,对每一步返回的left,right进行顺序归并>>>mergeSort(3,38, 5, 44, 15, 36)>>>[3, 5, 15, 36, 38, 44]"""if len(nums) < 2:return numsmid = len(nums)//2left, right = nums[:mid], nums[mid:]return mergeHelp(mergeSort(left), mergeSort(right))
  • 其中mergeHelp是mergeSort的一个help方法,用于对拆分后的数组进行顺序归并。
  • 以[3,38, 5, 44, 15, 36]举个栗子,说一下递归过程:
  • 1:[3, 38, 5] [44, 15, 36]
    2:[3] [38, 5]
    3:[38] [5]
    4:[44] [15, 36]
    5:[15] [36]

  • 接下来我们实现mergeHelp方法,就是给定两个有序数组,将其按顺序合并为一个数组,代码如下:
def mergeHelp(left, right):"""归并排序的help方法,用于将拆分的left和right进行顺序归并>>>mergeHelp([1, 3, 5], [2, 4, 5]):>>>[1, 2, 3, 4, 5, 5]"""res = []while left and right:if left[0] <= 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
  • 当我们实现了这个方法之后,看一下分割+归并的过程
  • [3, 38, 5] [44, 15, 36]  第一次分割
    左数组[3, 38, 5]部分:
    [3] [38, 5]  第一次分割
    [38] [5]  第二次分割(左数组分割完毕,所有部分元素均为1)
    [5, 38]  第一次归并
    [3, 5, 38]emsp; 第二次归并,完成[3, 38, 5]部分序列的排序
    右数组[44, 15, 36]部分:
    [44] [15, 36]  第一次分割
    [15] [36]  第二次分割
    [15, 36]  第一次合并
    [15, 36, 44]  第二次合并
    原数组的所有子序列完成排序,进行最终的合并
    [3, 5, 15, 36, 38, 44]  排序完成

  • 算法解析:算法的时间复杂度从两个部分分来来看,很明显在mergeSort()递归方法里面,迭代公式为mid = len(nums)//2,该方法的时间复杂度是O(log n),而在mergeHelp()归并方法里面,每一步像res里面追加一下元素,最终的的运行次数为len(left)+len(right),很明显时间复杂度为O(n),因此归并排序算法的总时间复杂度为O(n log n)。由于算法运行过程中,会递归生成原数组的切片,切片总长度为n,所以归并排序算法的空间复杂度为O(n)。
  • 注意到我们在进行归并操作是,使用的是如下代码
while left and right:if left[0] <= right[0]:res.append(left.pop(0))else:res.append(right.pop(0))
  • 也就是说对于同样大小的元素,我们先插入位于左边的,而后插入右边的,因此归并排序不会改变相同元素的相对位置,因此该算法是稳定的。

排序算法专题-归并排序相关推荐

  1. 排序算法:归并排序、快速排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.归并排序: 1.工作原理: 归 ...

  2. 排序算法之--归并排序(好玩的一个算法o。o)快速入门

    排序算法之--归并排序(好玩的一个算法o.o) 下面是归并操作的基本思路(注意:是归并操作哦,不是归并排序哦) 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存 ...

  3. NOI提高级:排序算法之归并排序、快速排序

    图解排序算法(四)之归并排序 图解排序算法(四)之归并排序 - dreamcatcher-cx - 博客园 小学生图解排序算法:⑥归并排序 小学生图解排序算法:⑥归并排序_纯文笔记-CSDN博客_图解 ...

  4. 数据结构与算法:十大排序算法之归并排序

    数据结构与算法:十大排序算法之归并排序 package TopTenSortingAlgorithms;/*** 归并排序:Java** @author skywang* @date 2014/03/ ...

  5. [Alg]排序算法之归并排序

    [Alg]排序算法之归并排序 作者:屎壳郎 miaosg01@163.com 日期:Aug 2021 版次:初版 简介: 归并排序是一类在任何情况下都能保证Nlg⁡(N)N\lg(N)Nlg(N)的排 ...

  6. 【排序算法】归并排序(C语言)

    [排序算法]-- 归并排序(C语言) 目录 一.归并排序的原理 二.两个有序数组排序和合并 1. 原地排序 2. 创建临时空间 二.递归实现 三.非递归实现 1. 实现思路 2. 数组边界问题 3. ...

  7. 排序算法中——归并排序和快速排序

    冒泡排序.插入排序.选择排序这三种算法的时间复杂度都为 $O(n^2)$,只适合小规模的数据.今天,我们来认识两种时间复杂度为 $O(nlogn)$ 的排序算法--归并排序(Merge Sort)和快 ...

  8. 【DS】排序算法之归并排序(Merge Sort)

    一.算法思想 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作.其归并思想如下: 1)申请空间,使其大小为两个已经 ...

  9. c语言归并排序代码详细注释,C语言实现排序算法之归并排序详解

    排序算法中的归并排序(Merge Sort)是利用"归并"技术来进行排序.归并是指将若干个已排序的子文件合并成一个有序的文件. 一.实现原理: 1.算法基本思路 设两个有序的子文件 ...

  10. 排序算法-07归并排序(python实现)

    归并排序 概述 以归并操作为基础的排序算法,底层算法设计为分治法. 所谓分治法,就是讲问题分解为多个子问题递归求解,再将子问题答案合并. 算法实现 将待排序序列分解为两个,四个,,,n个子部分. 两两 ...

最新文章

  1. python类的继承super方法_Python类的继承super相关原理解析
  2. 挖矿为什么要用显卡_Eth2拉开序幕,为何显卡大户却在加码挖矿?
  3. OSG官方自带的例子程序简介
  4. box2dweb 学习笔记--sample讲解
  5. 开源的商业意义_为开源项目提供资金具有良好的商业意义
  6. 涨价妥妥的!一加7 Pro欧洲价格曝光:顶配或超6000
  7. 虚拟化时代 智能数据管理架构才是王道
  8. linux oracle 10g dataguard 实施详细记录
  9. 06. Django基础:GET请求和POST请求
  10. Linux 内核md5sum使用,linux命令详解:md5sum命令(示例代码)
  11. 激光雷达SLAM三维建图、点云算法 点云处理 自己写的算法 没用任何现成的库文件
  12. 解决微信网页授权:出现errcode:40163
  13. 微软拼音中设置小鹤双拼
  14. 文件不见还占用空间咋修复
  15. 卡尔曼滤波最完整公式推导
  16. ML:图像数据、字符串数据等计算相似度常用的十种方法(余弦相似性、皮尔逊、闵可夫斯基距离/曼哈顿距离/欧氏距离/切比雪夫距离、马氏距离、汉明距离、编辑距离、杰卡德相似系数、相对熵/KL散度、Helli
  17. Sqli-labs Less7
  18. 263邮件服务器地址,263企业邮箱 服务器IP汇总
  19. 【有利可图网】PS实战系列:制作饼干字特效
  20. 支持Apple pay支付的设备

热门文章

  1. python项目练手(一)------飞船大战游戏
  2. c语言getchar的作用,c=getchar()!='\n'到底什么用呢
  3. oracle分区索引优化,SQL优化思路结果集重用优化、分区索引优化测试
  4. c++实现超声回波包络检测_学术简报新型电磁超声换能器,小尺寸板材缺陷检测效率高...
  5. python柱形图绘制_Python Excel 绘制柱形图
  6. MySQL查询日期类数据常用函数
  7. Go基础:不同数据类型作为函数参数传递值传递/地址(引用)传递判断
  8. JavaWeb:HTTP、Request、Response
  9. 实战HTML:根据参数构造动态设备监测列表
  10. HTML:canvas画圆形加矩形组合