有趣的事,Python永远不会缺席!

一、归并排序(MERGE-SORT)概念

  归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序适用于子序列有序的数据排序。

1、原理

  归并排序是分治法的典型应用。分治法(Divide-and-Conquer):将原问题划分成 n 个规模较小而结构与原问题相似的子问题;递归地解决这些问题,然后再合并其结果,就得到原问题的解。从上图看分解后的数列很像一个二叉树。

归并排序采用分而治之的原理:

  1. 将一个序列从中间位置分成两个序列;
  2. 在将这两个子序列按照第一步继续二分下去;
  3. 直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列即可。

              原理如上图,图片来源于https://blog.csdn.net/su_bao/article/details/81053871

2、举例

  1. 对以下数组进行归并排序: 
[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]

  2. 首先,进行数组分组,即

[11, 99, 33 , 69, 77, 88, 55],    [ 11, 33, 36,39, 66, 44, 22]
[11, 99, 33] ,     [69, 77, 88, 55],    [ 11, 33, 36],    [39, 66, 44, 22]
[11],     [99, 33] , [69, 77], [88, 55],[ 11], [33, 36],[39, 66], [44, 22]

  直到所有子序列的长度都为1,也就是不可以再二分截止。

[11], [99], [33] , [69], [77], [88], [55],[ 11], [33], [36],[39], [66], [44], [22]

  3. 这时候再两两合并成一个有序序列即可。

[11],[33,99],[69,77],[55,88],[11],[33,36],[39,66],[22,44]
[11,33,99],[55,69,77,88],[11,33,36],[22,39,44,66]
[11,33,55,69,77,88,99],[11,22,33,36,39,44,66]

  4、最终排序

[11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

  1. 二、代码

  代码用jupyternotebook实现

 def merge_sort(arr):
"""归并排序"""
if len(arr) == 1:
return arr
# 使用二分法将数列分两个
mid = len(arr) // 2
left = arr[:mid]
right = arr[mid:]
# 使用递归运算
return marge(merge_sort(left), merge_sort(right)) def marge(left, right):
"""排序合并两个数列"""
result = []
# 两个数列都有值
while len(left) > 0 and len(right) > 0:
# 左右两个数列第一个最小放前面
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
# 只有一个数列中还有值,直接添加
result += left
result += right
return result merge_sort([11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]) # 返回结果[11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

   这里记录一下,python有一个模块,专门提供了归并排序的方法,叫做“heapq”模块,因此我们只要将分解后的结果导入该方法即可。例如:

 from heapq import merge

 def merge_sort(lst):
if len(lst) <= 1:
return lst # 从递归中返回长度为1的序列
middle = len(lst) // 2
left = merge_sort(lst[:middle]) # 通过不断递归,将原始序列拆分成n个小序列
right = merge_sort(lst[middle:])
return list(merge(left, right)) merge_sort([11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]) # 返回结果[11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

三、特点

  1. 比较性:排序时元素之间需要比较,所以为比较排序

  2. 稳定性:我们从代码中可以看到当左边的元素小于等于右边的元素就把左边的排前面,而原本左边的就是在前面,所以相同元素的相对顺序不变,故为稳定排序

  3. 时间复杂度:    复杂度为O(nlog^n)

  4. 空间复杂度:在合并子列时需要申请临时空间,而且空间大小随数列的大小而变化,所以空间复杂度为O(n)

  5. 记忆方法:所谓归并肯定是要先分解,再合并

结果   

  Successfully !!!

  有趣的事,Python永远不会缺席!还不来加我,瞅什么瞅。

Python排序算法(六)——归并排序(MERGE-SORT)的更多相关文章

  1. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  2. 排序算法二:归并排序(Merge sort)

    归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是O(nlgn). (一)算法实现 private void merge_sort(int[] array, int ...

  3. 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)

    连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...

  4. python 排序算法总结及实例详解

    python 排序算法总结及实例详解 这篇文章主要介绍了python排序算法总结及实例详解的相关资料,需要的朋友可以参考下 总结了一下常见集中排序的算法 排序算法总结及实例详解"> 归 ...

  5. Java常见排序算法之归并排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  6. Python排序算法之选择排序定义与用法示例

    Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...

  7. 带你掌握4种Python 排序算法

    摘要:在编程里,排序是一个重要算法,它可以帮助我们更快.更容易地定位数据.在这篇文章中,我们将使用排序算法分类器对我们的数组进行排序,了解它们是如何工作的. 本文分享自华为云社区<Python ...

  8. java排序算法之冒泡排序(Bubble Sort)

    java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...

  9. python排序算法实现(冒泡、选择、插入)

    python排序算法实现(冒泡.选择.插入) python 从小到大排序 1.冒泡排序: O(n2) s=[3,4,2,5,1,9] #count = 0 for i in range(len(s)) ...

  10. 44.python排序算法(冒泡+选择)

    一,冒泡排序: 是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个,如果他们的排序错误就把他们交换过来. 冒泡排序是稳定的(所谓稳定性就是两个相同的元素不会交换位置) 冒泡排序算法的运作如下 ...

随机推荐

  1. UniPush使用指南

    原贴:https://ask.dcloud.net.cn/article/35622 UniPush使用指南 分类:uni-app Push unipush 从HBuilderX 1.7.2起,uni ...

  2. 一台服务器部署多台tomcat

    如题,多个项目部署在一台服务器.减少容错性,觉得分开部署,这样一个tomcat挂了不会影响另一个项目.看配置和应用大小决定数量,一般四五个没问题,也有单台服务器部署8个tomcat稳定运行的. 下面记 ...

  3. linux中导入sql文件

    在linux中导入sql文件的方法分享(使用命令行转移mysql数据库) 因导出sql文件 在你原来的网站服务商处利用phpmyadmin导出数据库为sql文件,这个步骤大家都会,不赘述. 上传sql ...

  4. Python - Django - CSRF

    CSRF 攻击: 把 settings.py 中的 csrf 注释掉 正规网站: 创建修改密码页面 password.html: <!DOCTYPE html> <html lang ...

  5. Java基础教程:多线程基础——线程池

    Java基础教程:多线程基础——线程池 线程池 在正常负载的情况瞎,通过为每一个请求创建一个新的线程来提供服务,从而实现更高的响应性. new Thread(runnable).start() 在生产 ...

  6. INTEL 7代CPU I5 7500 集显HD630 WIN7 64位

    HD630 在WIN7 下的硬件ID  (在设备管理器 - 显卡 - 属性 中查看): PCI\VEN_8086&DEV_5912&SUBSYS_D0001458&REV_04 ...

  7. 获取本机IP地址[JavaScript / Node.js]

    --web客户端JavaScript <body onload="checkCookie()"></body> function getYourIP(){ ...

  8. 基于libuv的TCP设计(三)

      基于libuv的TCP设计(一) 基于libuv的TCP设计(二)   一.第二版本的libuv_tcp已经基本可以使用.不会出错与崩溃现象,支持几百路客户端同时连接.可是有一缺陷就占用CPU非常 ...

  9. vue el-table 自适应表格内容宽度

    由于表头和列是分开渲染的,通过el-table 设置fit属性,只能撑开表头,但是没有办法根据列的内容去适应宽度.网上找了一些使用根据表格内容计算表头宽度的文章,记个笔记. 代码逻辑是通过vue  的 ...

  10. 什么?Iconfont终于可以支持彩色图标了

    如果你对iconfont有所了解,那你一定对这次iconfont做出的更新产生兴趣.没错,iconfont目前已经升级为iconfont+,并且能够支持大家都很期待的彩色图标. 之前,大家也以文字的形 ...