【算法】Merge Sort 合并排序

Merge Sort概述

分而治之算法

递归地将问题分解为多个子问题,直到它们变得简单易解
将解决方案组合起来,解决原有问题

O(n*log(n))运行时间

基于比较的算法的最佳运行时间

一般原则
·合并排序:
1. 将数组分成两半
2.在每一半上调用合并排序以递归排序
3.将两个已排序的两半合并为一个已排序数组

看一个例子:

2,6,5,1,7,4,3

首先第一步,是将数组分成两半,分到直到分不了了。

然后现在,对每组数据进行排序。

2,6

1,5

4,7

然后,再一组一组排序:
1,2,5,6

3,4,7

然后最后两组排序

1,2,3,4,5,6,7

注意这里是,1和3比,选1,2和3比,选2,5和3比,选3,4和5比,选4。。。

Python实现MergeSort合并排序

def merge_sort(arr):if len(arr) > 1: #要保证大于1才能排序left_arr = arr[:len(arr)//2] #定义2个子数组,这个是从索引0到中心点,:左留下空白就是取左边所有right_arr = arr[len(arr)//2:] #这个是从中心点到右边# 递归merge_sort(left_arr)merge_sort(right_arr) #分别再左右两个数组进行递归# 执行以上两行以后,左右两个数组都按照顺序排列了# 合并# 现在两个数组已经拍好顺序,我们想让两个数组,第一个数组的最左边和第二个数组最左边进行比较# 所以,创建索引进行追踪i = 0 #追踪第一个左边数组j = 0 #追踪右边k = 0 #追踪合并数组中的索引while i < len(left_arr) and j < len(right_arr):if left_arr[i] < right_arr[j]:#如果左边的数组值小arr[k] = left_arr[i] # 保存索引对应的值i += 1#k += 1#因为我们取得是i的值,所以,必须i+1进入下一个索引,而且,k是合并后的数组,也要进入下一个else:arr[k] = right_arr[j]j += 1#k += 1k += 1  #简略后,放这里# 现在只考虑转移左边的数组,不考虑右边的数组;# 这是假设,右边都排好了,但是左边没排完while i < len(left_arr):arr[k] = left_arr[i]i += 1k += 1# 假设左边都排好了,但是右边还要排while j < len(right_arr):arr[k] = right_arr[j]j += 1k += 1arr_test = [2,3,5,1,7,4,4,4,2,6,0]
merge_sort(arr_test)
print(arr_test)

问题:
 

 merge_sort(left_arr)
2    merge_sort(right_arr) #分别再左右两个数组进行递归
3    # 执行以上两行以后,左右两个数组都按照顺序排列了    这里是什么意思?是直接调用我定义的函数吗?函数不是没写完吗?

这里正是体现了递归函数的工作原理。当你在代码中调用 merge_sort(left_arr)merge_sort(right_arr) 时,你实际上是在调用当前函数自身,但是传入了不同的参数——即左侧子数组和右侧子数组。

虽然从直观上看,函数“还没有写完”,但实际上,每次调用 merge_sort 函数时,它都在执行完整的逻辑流程:

  1. 检查当前数组的长度是否大于1,如果是,则继续执行。
  2. 将当前数组分割成两个子数组(左侧和右侧)。
  3. 对这两个子数组分别递归调用 merge_sort 函数。这里就是递归发生的地方,每一次这样的调用都会重复整个过程,直到数组被拆分到不能再拆分(即长度为1或0,视为已排序)。
  4. 最后,通过合并这些小数组来完成排序。

因此,即便在某次调用中函数尚未执行到合并步骤,之前的调用(处理更小规模数组的那些调用)已经在逐步完成它们的任务。当这些更深层次的递归调用返回时,它们会逐级返回到上一层,最终回到最初的函数调用,这时所有子数组都已经排序完毕,可以进行最终的合并,完成整个数组的排序。

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

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

相关文章

【瞎折腾日常】服务器的cpu飙高到1000%了怎么破

一、故障起因 起因是用户反馈系统很卡,我登录普罗米修斯一看,发现docker部署得集群下的一个java应用服务器cpu爆了,直接冲到了1000%以上了,接着就是各种接口超时报警等,赶紧打开对应的服务器查看进程情况,这会使用jstack和top命令定位哪个线程占用的cpu比较大,定位代码问…

椭流线法设计配光器

椭流线法设计配光器 一、设计原理 1、边光原理 边光原理是非成像光学中的一个基础原理&#xff0c;其内容可以表述为&#xff1a;来自光源边缘的光线经过若干有序正则光学曲面后依然落在投射光斑的边缘&#xff0c;而来自光源内部的光线也将落在光斑内部。这里的边缘包含两层…

机械拆装-基于Unity-总体设计

前言 在工业设计和制造领域&#xff0c;零部件的拆装技术是一个重要的应用场景&#xff0c;比如我们在工程训练课程中经历的摩托车发动机拆装课程&#xff0c;是机械类学生的必修课程。虚拟拆装系统模拟和仿真了模型的拆装过程&#xff0c;虽然SolidWorks等机械设计软件能够解决…

性能调优 性能监控

1.影响性能考虑点包括&#xff1a; 数据库、应用程序、中间件(tomcat、nginx)、网络和操作系统等方面。 首先考虑自己的应用属于 CPU密集型 还是 IO密集型 cpu密集型 计算&#xff0c;排序&#xff0c;分组查询&#xff0c;各种算法 IO密集型 网络传输&#xff0c;磁盘读…

大创项目推荐 题目:基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python

文章目录 1 简介2 传统机器视觉的手势检测2.1 轮廓检测法2.2 算法结果2.3 整体代码实现2.3.1 算法流程 3 深度学习方法做手势识别3.1 经典的卷积神经网络3.2 YOLO系列3.3 SSD3.4 实现步骤3.4.1 数据集3.4.2 图像预处理3.4.3 构建卷积神经网络结构3.4.4 实验训练过程及结果 3.5 …

zabbix报警机制,主动监控

zabbix思路流程 主动监控 默认zabbix使用的是被动监控&#xff0c;主被动监控都是针对被监控主机而言的。被动监控&#xff1a;Server向Agent发起请求&#xff0c;索取监控数据。此种模式常用主动监控&#xff1a;Agent向Server发起连接&#xff0c;向Server汇报 配置web2使用…

STM32智能家居掌上屏实战:从WiFi连接到MQTT通信,打造你的家庭物联网网关

摘要: 本文深入探讨一种基于STM32的智能家居掌上屏设计方案&#xff0c;详细阐述其硬件架构、软件设计以及通信协议等关键技术细节。该方案利用WiFi构建局域网&#xff0c;实现与各类传感器、执行器的便捷交互&#xff0c;并通过TFT彩屏提供直观的控制和数据展示&#xff0c;旨…

[数据库原理]事务

如有错误&#xff0c;欢迎指正&#xff01;&#xff01;&#xff01; 期末考了冲突可串行化

动态顺序表实现通讯录

系列文章目录 【数据结构】顺序表 文章目录 系列文章目录前言一、通讯录的功能要求二、通讯录的代码实现1. 新建文件2. 创建通讯录的结构体3. 对顺序表文件进行修改4. 通讯录具体功能实现4.1. 通讯录的初始化和销毁4.2. 增加联系人信息&#xff08;尾插&#xff09;4.3. 查找指…

SpringBoot + 虚拟线程,性能炸裂!

一、什么是虚拟线程 虚拟线程是Java19开始增加的一个特性&#xff0c;和Golang的携程类似&#xff0c;一个其它语言早就提供的、且如此实用且好用的功能&#xff0c;作为一个Java开发者&#xff0c;早就已经望眼欲穿了。 二、虚拟线程和普通线程的区别 “虚拟”线程&#xf…

一些硬件知识(十二)

X电容是接在火线和零线之间&#xff0c;Y电容是接在火零线和地之间。X电容滤除差模干扰&#xff0c;Y电容滤除共模干扰&#xff1a; 高频干扰信号经过X电容后幅度没有变化&#xff0c;相位相差180度&#xff1a; DW01电池管理芯片&#xff1a; M1、M2&#xff1a;这两个为N沟道…

【关于C/C++中的scanf不能使用问题】

方法1&#xff1a;scanf_s 方法2&#xff1a;看见后面的日志了吗 CRT……&#xff1f;在第一行加上#define 日志 方法3&#xff1a;#pragma warning&#xff08;disable&#xff1a;4996&#xff09; 4996是我们的报错序号

开发笔记:vue3+ts+vant 卡片数据分页,下拉加载,卡片左滑可删除

效果&#xff1a; 实现 使用vantui组件 van-swipe-cell van-card &#xff08;商品卡片&#xff09; 核心代码 const currentPage ref(1) const pageSize ref(4) const totalSize ref(10) const loading ref(false) const finished ref(false) const refreshing ref(…

Git新仓库创建流程

平时需要创建新仓库,老要去查代码特别烦&#xff0c;在此写下流程方便备用. 1.创建新的云仓库 无论使用GitHub还是Gitee,首先要创建一个云仓库&#xff0c;这里就直接用国内的gitee做演示了&#xff0c;githup老挂加速器太烦&#xff0c;偷个懒. 我这里创建的是一个空仓库&…

Nginx主配置文件---Nginx.conf

nginx主配置文件的模块介绍 全局块&#xff1a; 全局块是配置文件从开始到 events 块之间的部分&#xff0c;其中指令的作用域是 Nginx 服务器全局。主要指令包括&#xff1a; user&#xff1a;指定可以运行 Nginx 服务的用户和用户组&#xff0c;只能在全局块配置。例如&…

软考《信息系统运行管理员》-2.2 信息系统运维的组织

2.2 信息系统运维的组织 信息系统运维的任务 数据资源管理 数据收集、数据校验、数据录入、数据处理 软件资源管理 采购、保存、相关文档保管、分发、安装、支持、评价、培训 硬件资源管理 检查、维护、故障处理、更新、修复、扩充 系统安全管理 可用性、完整性、保密性、可控…

USB PD+TYPE -C快充电源中MOSFET选型,USB PD应用市场包含智能手机,平板电脑,笔记本电脑,游戏本,移动硬盘,数码相机,电动工具等传统领域

USB PD全称为USB Power Delivery&#xff0c;是由USB-IF组织制定的一种快速充电协议&#xff0c;也是目前市场非常看好的一种协议&#xff0c;可以支持输出功率高达100W&#xff1b;Type-C是一种接口规范&#xff0c;能够支持传输更大的电流。USB PD应用市场不仅包含智能手机&a…

虚拟纪念展馆建设的重大意义:重新定义纪念活动的未来

一、什么是虚拟纪念展馆&#xff1f; 虚拟纪念展馆是一种利用3D、VR等技术在线展示历史事件、人物或文化遗产的数字化空间。这些展馆通过虚拟现实、增强现实和3D建模等技术手段&#xff0c;创建出身临其境的体验&#xff0c;使参观者可以在互联网上以互动方式探索和学习。 二、…

【FPGA 学习与实践】<初阶> 项目周计划

第1-2周&#xff1a;基础项目 - 4位加法器和计数器 目标&#xff1a;掌握Verilog基本语法和模块设计。 第1周&#xff1a; 学习Verilog的基本语法和结构&#xff08;模块、端口、数据类型&#xff09;。设计并实现一个4位加法器。编写测试平台&#xff08;Testbench&#xff0…

提升效率就靠它们啦

Hey小伙伴们&#xff5e;&#x1f44b; 知道你们都在忙碌的工作中寻求高效的秘诀&#xff0c;今天就给大家安利五款超实用的国产工作App&#xff0c;让你的工作生活更加得心应手哦&#xff01;&#x1f4bc;✨ 1️⃣【亿可达】 作为一款自动化工具&#xff0c;亿可达被誉为国内…