基于Python3的数据结构与算法 - 07 归并排序

一、归并

引入

假设现在的列表分两段有序,如何将其合并成为一个有序列表。

这种操作成为一次归并。

归并的思路

  1. 分别对两个列表进行遍历,比较两个列表中的最小值,将更小的取出来。
  2. 取出后一次进行上操作,直到其中一个列表中的元素被取完。
  3. 再直接将列一个列表中的剩下元素全部取出。

实现代码如下:

def merge(li, low, mid, high):# 两个列表合并一块,最左边为low,最右边为high,第一个列表的最后一个元素下标为mid# 则列表被分为两部分,一个为low - mid,另一个为mid+1 - high# 最开始定义两个箭头 + 一个存放返回的空列表i = lowj = mid +1ltmp = []while i<= mid and j <= high:if li[i] < li[j]:  # 此时i小,则将i对应的数取出,箭头向下移动一位ltmp.append(li[i])i += 1else:ltmp.append(li[j])j += 1# 当while执行完后必定是两部分中的一个没有剩余数字while i <= mid:   #对应左边的列表还有剩余ltmp.append(li[i])i += 1while j <= high:   #对应右边的列表还有剩余ltmp.append(li[j])j += 1# 最后将数值返回lili[low:high+1] = ltmpli = [1,4,7,2,5,8]
print(li)
merge(li, 0, 2, 5)
print(li)

输出结果如下:

此时我们实现了将两个有序列表合并为一个有序列表。

二、归并排序的实现

大致分为三步:

  • 分解:将列表越分越小,直至分成一个元素。
  • 终止条件:一个元素是有序的
  • 合并:将两个有序列表归并,列表越来越大。

代码的思路:主要运用了递归,对于整个无序列表,我们想要将其变为有序列表,主要采用以下三步:

  1. 确定好mid后,先将左边的排为有序
  2. 再将右边的拍为有序
  3. 最后采用上面提到的归并的思路,将两个有序的列表归并为一个列表。
def merge_sort(li, low, high):if low <  high:mid = (low+high) // 2merge_sort(li,low,mid)merge_sort(li,mid+1,high)merge(li,low,mid,high)li = [1,4,7,2,5,8,3,6,9]
print(li)
merge_sort(li, 0, len(li)-1)
print(li)

输出的结果如下:

因此,整个综合代码如下所示:

def merge(li, low, mid, high):# 两个列表合并一块,最左边为low,最右边为high,第一个列表的最后一个元素下标为mid# 则列表被分为两部分,一个为low - mid,另一个为mid+1 - high# 最开始定义两个箭头 + 一个存放返回的空列表i = lowj = mid +1ltmp = []while i<= mid and j <= high:if li[i] < li[j]:  # 此时i小,则将i对应的数取出,箭头向下移动一位ltmp.append(li[i])i += 1else:ltmp.append(li[j])j += 1# 当while执行完后必定是两部分中的一个没有剩余数字while i <= mid:   #对应左边的列表还有剩余ltmp.append(li[i])i += 1while j <= high:   #对应右边的列表还有剩余ltmp.append(li[j])j += 1# 最后将数值返回lili[low:high+1] = ltmpdef merge_sort(li, low, high):if low <  high:mid = (low+high) // 2merge_sort(li,low,mid)merge_sort(li,mid+1,high)merge(li,low,mid,high)li = [1,4,7,2,5,8,3,6,9]
print(li)
merge_sort(li, 0, len(li)-1)
print(li)

 三、归并排序的复杂度

1. 时间复杂度

一次归并的时间复杂度为O(n),可以参考上图中的分解和合并考虑归并算法的时间复杂度。

每次进行的操作的复杂度为O(n),共有O(logn)层,因此总共的时间复杂度为O(nlogn)

2. 空间复杂度

因为在merge中我们开辟了一个空间ltmp[],因此空间复杂度为O(n).

pyhton中的sort方法是基于归并排序的。

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

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

相关文章

springboot+vue实现Minio文件存储

安装minio 首先点击进入MINIO官网&#xff0c;进行一个minio服务器的下载 下载好了之后在本地磁盘找一个文件夹&#xff0c;把下载的exe放入文件夹&#xff0c;再新建一个文件夹准备存放数据和文件 在当前目录cmd进入控制台&#xff0c;输入代码 minio.exe server data成功后…

内衣洗衣机什么牌子好又便宜?实力非凡机型深度测评

内衣裤这种小件的衣物紧密接触皮肤&#xff0c;更是接触特殊生理部位&#xff0c;所以&#xff0c;内衣裤对卫生标准有着特殊要求&#xff0c;现在很多人都是&#xff0c;把内衣裤放到家里的大型洗衣机和其他衣物混洗&#xff0c;你应该知道大型洗衣机由于长期清洗一些大件的衣…

MySQL 8.0.35 企业版比社区版性能高出 25%?

前言 说实话&#xff0c;比较一下这两个 MySQL 发行版&#xff0c;并不会让我很兴奋。这是因为在我关于 MySQL 的记忆中&#xff0c;如果是谈代码库时&#xff0c;两个发行版之间没有真正的区别。 据我所知&#xff0c;企业版的差异在于附加的插件/组件&#xff0c;因此除非您…

简单版 git快速上手使用 clone项目 新建/切换分支 提交修改

Git是一个广泛使用的版本控制系统&#xff0c;允许多个用户跟踪文件的更改&#xff0c;并协作开发项目。 首先确定自己电脑已经安装了git&#xff0c;具体安装步骤请查找教程&#xff0c;应该不难。 以windows电脑为例&#xff0c;安装完后在搜索栏搜索git会出现 先解释一下这…

C# OpenVINO Nail Seg 指甲分割 指甲检测

目录 效果 模型信息 项目 代码 数据集 下载 C# OpenVINO Nail Seg 指甲分割 指甲检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-02-29T16:41:28.273760 author&#xff1a;Ultralytics task&#xff1a;segment version&#…

【GitHub】修改默认分支

GitHub的默认分支为main&#xff0c;但我们常常习惯使用master作为默认分支&#xff0c;那在GitHub上如何将master修改为默认分支呢&#xff1f; 全局修改 点击头像&#xff0c;选择菜单栏中的设置 输入master作为默认分支&#xff0c;然后执行updating即可&#xff01; 单项…

springboot+vue实现oss文件存储

前提oss准备工作 进入阿里云官网&#xff1a;阿里云oss官网 注册 搜OSS&#xff0c;点击“对象存储OSS” 第一次进入需要开通&#xff0c;直接点击立即开通&#xff0c;到右上角AccessKey管理中创建AccessKey&#xff0c;并且记住自己的accessKeyId和accessKeySecret&#…

【Unity】构建简单实用的年份选择器(简单原理示范)

在许多应用程序和游戏中&#xff0c;年份选择是一个常见的需求。无论是在日历应用程序中查看事件&#xff0c;还是在历史类游戏中选择时间段&#xff0c;年份选择器都是用户体验的重要组成部分&#xff0c;下面实现一个简易的年份选择器。 一、效果预览&#xff1a; 目录 一、…

树莓派驱动编译

驱动编译前提&#xff1a;驱动代码的编译需要提前编译号的内核 驱动&#xff08;3种实现方法&#xff0c;2条路线&#xff09;_驱动编写三种方法-CSDN博客 驱动的编写_驱动编写-CSDN博客 一、概念 1.1、驱动认识 1、裸机程序中是直接操控硬件的&#xff0c;操作系统…

力扣-跳跃游戏

问题 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 解答 class Solu…

C++ 入门(八)— 常量和字符串

常量和字符串 常量变量常量表达式编译时优化 Constexpr 变量std::string字符串输出 std::coutstd::string可以处理不同长度的字符串字符串输入 std::cin用于输入文本std::getline()不要按值传递Constexpr 字符串 std::string_view可以使用许多不同类型的字符串进行初始化可以接…

v69.字符

1.字符类型 1.1 可以将char类型的变量赋值为整数&#xff0c;也可以赋值为字符! 注意字符要用单引号 ’ ’ 而不是双引号 每一个字符在计算机内部都有一个值去表达它。字符’1’ 在计算机里表示的十进制的整数值为49&#xff0c;就像’A’表示十进制值65。 1.2 scanf 与 p…

C++面试宝典第33题:数组组成最大数

题目 给定一组非负整数nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。 示例1: 输入:nums = [10, 2] 输出:"210" 示例2: 输入:nums = [3, 30, 34, 5, 9] 输出:"…

【查漏补缺你的Vue基础】Vue数据监听深度解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【rust】10 project、crate、mod、pub、use、项目目录层级组织、概念和实战

文章目录 一、项目目录层级组织概念1.1 cargo new 创建同名 的 Project 和 crate1.2 多 crate 的 package1.3 mod 模块1.3.1 创建嵌套 mod1.3.2 mod 树1.3.3 用路径引用 mod1.3.3.1 使用绝对还是相对? 1.3.4 代码可见性1.3.4.1 pub 关键字1.3.4.2 用 super 引用 mod1.3.4.3 用…

阿里Java开发手册(黄山版) LeetCode刷题手册 免费下载

目录 一、阿里Java开发手册(黄山版) 二、LeetCode刷题手册 三、获取方式 今天给大家推荐两个程序员的辅助利器&#xff01;都是平时开发&#xff0c;刷算法能经常用到的书籍&#xff0c;怕百度云分享会失效&#xff0c;获取方式在最下面&#xff0c;永久有效。 一、阿里Jav…

C++ 反向迭代器的设计与实现

在本文开始之前&#xff0c;先明晰几个 关键词 的含义&#xff08;T : 模板参数&#xff09;&#xff1a; Ref : T& / const T&Ptr : T* / const T* 一、反向迭代器设计的上帝视角 我们希望将 反向迭代器 设计成一种适配器——传 list::iterator 得到 list 的反向迭代…

Lastools工具使用

Lastools工具使用 1、介绍 官网链接 常用的功能 las2las可以进行点云拼接las2txt可以将点云中的有效信息转换为txt文档&#xff08;如xyz坐标&#xff09;lasmerge可以将多个LAS/LAZ文件合并为一个文件Laszip将LAS文件高速压缩到LAZ而不会丢失信息las2text将LAS/LAZ转换为可…

C++初阶:模版相关知识的进阶内容(非类型模板参数、类模板的特化、模板的分离编译)

结束了常用容器的介绍&#xff0c;今天继续模版内容的讲解&#xff1a; 文章目录 1.非类型模版参数2.模板的特化2.1模版特化引入和概念2.2函数模版特化2.3类模板特化2.3.1全特化2.3.1偏特化 3. 模板分离编译3.1分离编译概念3.2**模板的分离编译**分析原因 1.非类型模版参数 模板…

设计模式(五)-观察者模式

前言 实际业务开发过程中&#xff0c;业务逻辑可能非常复杂&#xff0c;核心业务 N 个子业务。如果都放到一块儿去做&#xff0c;代码可能会很长&#xff0c;耦合度不断攀升&#xff0c;维护起来也麻烦&#xff0c;甚至头疼。还有一些业务场景不需要在一次请求中同步完成&…