TypeScript 算法手册 【归并排序】
文章目录
- 1. 归并排序简介
- 1.1 归并排序定义
- 1.2 归并排序特点
- 2. 归并排序步骤过程拆解
- 2.1 分割数组
- 2.2 递归排序
- 2.3 合并有序数组
- 3. 归并排序的优化
- 3.1 原地归并排序
- 3.2 混合插入排序
- 案例代码和动态图
- 4. 归并排序的优点
- 5. 归并排序的缺点
- 总结
【 已更新完 TypeScript 设计模式 专栏,感兴趣可以关注一下,一起学习交流🔥🔥🔥 】
1. 归并排序简介
1.1 归并排序定义
归并排序是一种高效的、基于比较的排序算法,它的核心思想是"分而治之"。假设你是一个厨师,需要制作一大锅复杂的汤。你采用这样的策略:首先将食材分成两组,放在两个锅里,你继续将每个锅里的食材再分成两份,直到每个小锅里只有一种食材。你开始两两比较相邻小锅里的食材,将它们按照口味搭配合并到一个新的锅中,不断重复这个过程,直到所有的食材都被合并到一个完美调和的大锅汤里。这就是归并排序的基本思想。
用TypeScript代码表示一个简单的归并排序:
function mergeSort(arr: number[]): number[] {if (arr.length <= 1) return arr;const mid = Math.floor(arr.length / 2);const left = arr.slice(0, mid);const right = arr.slice(mid);return merge(mergeSort(left), mergeSort(right));
}function merge(left: number[], right: number[]): number[] {let result: number[] = [];let leftIndex = 0;let rightIndex = 0;while (leftIndex < left.length && rightIndex < right.length) {if (left[leftIndex] < right[rightIndex]) {result.push(left[leftIndex]);leftIndex++;} else {result.push(right[rightIndex]);rightIndex++;}}return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
1.2 归并排序特点
- 分治思想: 归并排序采用分治策略,将复杂问题分解为简单子问题
- 稳定性: 归并排序是稳定的排序算法
- 时间复杂度: 无论最好、最坏还是平均情况,时间复杂度都是O(nlogn)
- 空间复杂度: 需要额外的O(n)空间
2. 归并排序步骤过程拆解
2.1 分割数组
const mid = Math.floor(arr.length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid);
如厨师将一大堆食材分成两份,他们不断地分割,直到每个小碗里只剩下一种食材。
2.2 递归排序
return merge(mergeSort(left), mergeSort(right));
这个步骤就像每个厨师都在独立地整理自己那一小堆食材,只有一种食材时,它自然就是有序的。
2.3 合并有序数组
function merge(left: number[], right: number[]): number[] {let result: number[] = [];let leftIndex = 0;let rightIndex = 0;while (leftIndex < left.length && rightIndex < right.length) {if (left[leftIndex] < right[rightIndex]) {result.push(left[leftIndex]);leftIndex++;} else {result.push(right[rightIndex]);rightIndex++;}}return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
这个步骤就像两位厨师比较各自盘子里最小的食材,将较小的那个放到新的大盘子中,不断重复这个过程,直到所有的食材都合并到新的大盘子中,形成一道完整的菜肴。
3. 归并排序的优化
3.1 原地归并排序
function inPlaceMergeSort(arr: number[], start: number = 0, end: number = arr.length - 1): void {if (start >= end) return;const mid = Math.floor((start + end) / 2);inPlaceMergeSort(arr, start, mid);inPlaceMergeSort(arr, mid + 1, end);inPlaceMerge(arr, start, mid, end);
}function inPlaceMerge(arr: number[], start: number, mid: number, end: number): void {let left = start;let right = mid + 1;let temp: number[] = [];while (left <= mid && right <= end) {if (arr[left] <= arr[right]) {temp.push(arr[left]);left++;} else {temp.push(arr[right]);right++;}}while (left <= mid) {temp.push(arr[left]);left++;}while (right <= end) {temp.push(arr[right]);right++;}for (let i = 0; i < temp.length; i++) {arr[start + i] = temp[i];}
}
就像厨师在制作汤时,不是每次都拿出新的锅来装食材,而是直接在原来的大锅里进行操作。这样可以节省一些厨具空间,可能会稍微增加一些烹饪时间。
3.2 混合插入排序
function hybridMergeSort(arr: number[], threshold: number = 10): number[] {if (arr.length <= threshold) {return insertionSort(arr);}const mid = Math.floor(arr.length / 2);const left = arr.slice(0, mid);const right = arr.slice(mid);return merge(hybridMergeSort(left, threshold), hybridMergeSort(right, threshold));
}function insertionSort(arr: number[]): number[] {for (let i = 1; i < arr.length; i++) {let current = arr[i];let j = i - 1;while (j >= 0 && arr[j] > current) {arr[j + 1] = arr[j];j--;}arr[j + 1] = current;}return arr;
}
这个优化版本就像厨师在制作汤时,发现食材数量少于某个阈值(比如10种)时,直接用更简单的烹饪方法,这样可以减少复杂的烹饪步骤,提高整体的烹饪效率。
案例代码和动态图
const array = [38, 27, 43, 3, 9, 50, 10];
const sortedArray = mergeSort(array);
console.log(sortedArray); // [3, 9, 10, 27, 38, 43, 50]
4. 归并排序的优点
- 稳定性好: 归并排序是稳定的排序算法
- 时间复杂度稳定: 无论最好、最坏还是平均情况,时间复杂度都是O(nlogn)
- 适合外部排序: 当数据量很大,无法一次性加载到内存时,归并排序特别有用
5. 归并排序的缺点
- 空间复杂度高: 需要额外的O(n)空间
- 对于小规模数据,不如插入排序等简单算法效率高
总结
归并排序就像是一个团队合作的游戏。面对复杂的问题,先将其分解成小问题,各自解决后再合并结果。这种"分而治之"的思想不仅在排序算法中有用,在我们日常解决问题时也常常能派上用场。
归并排序的稳定性和时间复杂度的优势,使它在处理大规模数据时表现出色。特别是在外部排序中,当数据量大到无法一次性加载到内存时,归并排序的思想就显得尤为重要。
没有一种算法是完美的,归并排序的空间复杂度相对较高,在某些内存受限的场景中可能成为一个问题,对于小规模数据,它不如一些更简单的算法高效。因此了解每种算法的特点和适用场景,在实际应用中做出最佳选择。
喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!
下期预告: TypeScript 算法手册 - 快速排序
相关文章:
TypeScript 算法手册 【归并排序】
文章目录 1. 归并排序简介1.1 归并排序定义1.2 归并排序特点 2. 归并排序步骤过程拆解2.1 分割数组2.2 递归排序2.3 合并有序数组 3. 归并排序的优化3.1 原地归并排序3.2 混合插入排序案例代码和动态图 4. 归并排序的优点5. 归并排序的缺点总结 【 已更新完 TypeScript 设计模式…...
生信名词|MOA|基因敲低与基因敲除|DMSO|MODZ|生信基础
生信名词|MOA|基因敲低与基因敲除|DMSO|MODZ|生信基础 MOA(Mechanisms Of Action,作用机理) 过去,在药物投入到临床使用之前,它的生物学机理往往未被研究透彻。如今,随着技术的发展,一种新药物…...
基础岛第3关:浦语提示词工程实践
模型部署 使用下面脚本测试模型 from huggingface_hub import login, snapshot_download import osos.environ[HF_ENDPOINT] https://hf-mirror.comlogin(token“your_access_token")models ["internlm/internlm2-chat-1_8b"]for model in models:try:snapsh…...
vscode中配置python虚拟环境
python虚拟环境作用 Python虚拟环境允许你为每个独立的项目创建一个隔离的环境,这样每个项目都可以拥有自己的一套Python安装包和依赖,不会互相影响。实际使用中,可以在vscode或pycharm中使用虚拟环境。 1.创建虚拟环境的方法: …...
chatGPT对我学术写作的三种帮助
chatGPT对我学术写作的三种帮助 概述提高学术写作水平大模型选择概述上下文以提供精确的指令 提升同行评审优化编辑反馈 概述 从生成式人工智能中获得的价值并非来自于技术本身盲目地输出文本,而是来自于与工具的互动,并利用自身的专业知识来完善它所生…...
【PostgreSQL 】入门篇——支持的各种数据类型介绍,包括整数、浮点数、字符串、日期、JSON、数组等
1. 整数类型 1.1 SMALLINT 描述:用于存储小范围的整数值。大小:2 字节范围:-32,768 到 32,767使用场景:适合存储小型计数器、状态码等。示例: CREATE TABLE status_codes (id SMALLINT PRIMARY KEY,description TEX…...
野火STM32F103VET6指南者开发板入门笔记:【1】点亮RGB
硬件介绍 提示:本文是基于野火STM32F103指南者开发板所写例程,其他开发板请自行移植到自己的工程项目当中即可。 RGB-LEDPin引脚:低电平-点亮,高电平-熄灭REDPB5GREENPB0BLUEPB1 文章目录 硬件介绍软件介绍:结构体方式…...
数据工程师岗位常见面试问题-3(附回答)
数据工程师已成为科技行业最重要的角色之一,是组织构建数据基础设施的骨干。随着企业越来越依赖数据驱动的决策,对成熟数据工程师的需求会不断上升。如果您正在准备数据工程师面试,那么应该掌握常见的数据工程师面试问题:包括工作…...
强大的JVM监控工具
介绍 在生产环境中,经常会遇到各种各样奇葩的性能问题,所以掌握最基本的JVM命令行监控工具还是很有必要的 名称主要作用jps查看正在运行的Java进程jstack打印线程快照jmap导出堆内存映像文件jstat查看jvm统计信息jinfo实时查看和修改jvm配置参数jhat用…...
python 实现点的多项式算法
点的多项式算法介绍 点的多项式算法通常指的是通过一组点(即数据点,通常包括自变量和因变量的值)来拟合一个多项式函数的方法。这种方法在数值分析、统计学、机器学习等领域中非常常见。下面是一些常见的多项式拟合算法: 1. 最小…...
Pikachu-暴力破解-验证码绕过(on client)
访问页面, 从burpsuite 上看到返回的源代码; 验证码生成时通过 createCode 方法生成,在前端页面生成; 同时也是在前端做的校验; 直接验证;F12 -- 网络,随便输入个账号、密码、验证码࿰…...
【Spring】Bean 的生命周期:从实例化到销毁
实例化阶段: Bean的实例化是通过反射创建的。Spring根据Component、Bean或者XML中的<bean>元素配置,来确定要创建的Bean。 属性赋值阶段: 实例化完成后,Spring会进行依赖注入。包括将属性值注入到Bean的字段中,…...
Ubuntu 安装RUST
官方给的是这样如下脚本 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh 太慢了 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh -x 执行这个脚本后会给出对应的下载链接 如下图 我直接给出来 大多数应该都是这个 https://static.rust-…...
Android Compose的基本使用
前言: Compose这个东西呢,好处我没发现,坏处就是学习成本和低版本兼容. 不过,看在官方力推的份儿上,有空就学一下吧. 当初的kotlin,很多人说鸡肋(包括我)!现在不也咔咔用纯kotlin做项目吗?哈哈哈哈. 未来的事情,谁说得清呢? 首先创建一个专用的Compose项目 对没错!看到E…...
计算机网络:计算机网络体系结构 —— 专用术语总结
文章目录 专用术语实体协议服务服务访问点 SAP 服务原语 SP 协议数据单元 PDU服务数据单元 SDU 专用术语 实体 实体是指任何可以发送或接收信息的硬件或软件进程 对等实体是指通信双方处于相同层次中的实体,如通信双方应用层的浏览器进程和 Web 服务器进程。 协…...
Rust的前端Tauri编程-基于JS框架的初步探索
上次的项目做完后,有一项遗憾,没有返回结果,而结果是一个html表格,我想用html直接在窗口显示,这时发现R里面包括slint没有很直接的方法,直接弹出浏览器有点太简单没有挑战。这是就被推送了他的竞争对手&…...
【Flume Kafaka实战】Using Kafka with Flume
一 目标 在Cloudera Manager中创建两个Flume的Agent,Agent1从local file中获取内容,写入到kafka的队列中。Agent2以Agent1的sink作为source,将数据从kafka中读取出来,写入到HDFS中。 二 实战 2.1 Kafka Sink 第一步࿰…...
5G NR物理信号
文章目录 NR 物理信号与LTE的区别上行参考信号DMRS (UL)SRSPT-RS(UL) 下行参考信号DMRS(DL)PT-RS(DL)CSI-RSPSSSSS NR 物理信号与LTE的区别 用SSS、CSI-RS和DMRS 取代了CRS信号。下行业务信道采用TM1波束赋形传输模式。基于SSB 或者CSI-RS进行RSRP和SINR测量。基于DMRS 进行共…...
Pikachu-Cross-Site Scripting-存储型xss
存储型xss ,随便输入点内容,都能保存下来;刷新后也不会丢失;输入特殊字符,也能原样返回; 查看代码,也可以看到输出结果直接原路返回,不做处理 构造payload <script>alert(1)…...
媲美GPT-4o mini的小模型,Meta Llama 3.2模型全面解读!
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…...
【leetcode】 45.跳跃游戏 ||
如果我们「贪心」地进行正向查找,每次找到可到达的最远位置,就可以在线性时间内得到最少的跳跃次数。 例如,对于数组 [2,3,1,2,4,2,3],初始位置是下标 0,从下标 0 出发,最远可到达下标 2。下标 0 可到达的…...
coco(json)、yolo(txt)、voc(xml)标注格式的相互转换
一般都是用labeleme进行标注 标注格式都是json 然后根据不同的格式进行数据标注转换: 1.逐个json转xml: 当我们在使用数据集训练计算机视觉模型时,常常会遇到有的数据集只给了单个的json annotation文件,而模型所需要的annotation是基于每…...
以太网交换安全:端口安全
一、端口安全介绍 端口安全是一种网络设备防护措施,通过将接口学习到的动态MAC地址转换为安全MAC地址(包括安全动态MAC和Sticky MAC),阻止除安全MAC和静态MAC之外的主机通过本接口和设备通信,从而增强设备的安全性。以…...
[题解] Codeforces Round 976 (Div. 2) A ~ E
A. Find Minimum Operations 签到. void solve() {int n, k;cin >> n >> k;if (k 1) {cout << n << endl;return;}int ans 0;while (n) {ans n % k;n / k;}cout << ans << endl; }B. Brightness Begins 打表发现, 翻转完后的序列为: 0…...
【零基础入门产品经理】学习准备篇 | 需要学一些什么呢?
前言: 零实习转行产品经理经验分享01-学习准备篇_哔哩哔哩_bilibili 该篇内容主要是对bilibili这个视频的观后笔记~谢谢美丽滴up主友情分享。 全文摘要:如何在0实习且没有任何产品相关经验下,如何上岸产品经理~ 目录 一、想清楚为什么…...
第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)征稿
第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)由湖南第一师范学院主办,南京师范大学、山东女子学院、爱迩思出版社(ELSP)协办。 大会将专注于机器人、数字化、自动化、人工智能等技术的开发和融合,…...
[数据集][目标检测]电力场景防震锤缺陷检测数据集VOC+YOLO格式705张1类别
重要说明:防震锤缺陷图片太难找,数据集里面存在大量单一场景图片,请仔细查看图片预览谨慎下载,此外数据集均为小目标检测,如果训练map偏低属于正常现象 数据集格式:Pascal VOC格式YOLO格式(不包含分割路径…...
【SpringBoot】
目录 一、Spring Boot概要 1. SpringBoot介绍 2. SpringBoot优点 3. SpringBoot缺点 4. 时代背景-微服务 二、Spring Boot 核心配置 1. Spring Boot配置文件分类 1.1 application.properties 1.2 application.yml 1.3 小结 2. YAML概述 3. YAML基础语法 3.1 注意事…...
Linux操作系统中MongoDB
1、什么是MongoDB 1、非关系型数据库 NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了很多难以克服的问…...
2、.Net 前端框架:OpenAuth.Net - .Net宣传系列文章
OpenAuth.Net 是一个开源的身份验证框架,由开发者 Yubaolee 创建,它旨在简化 Web 应用和服务的安全授权过程。这个框架以其强大的功能和易用性,为开发人员提供了一种高效的方式来处理用户认证和授权问题。 OpenAuth.Net 的关键特性包括&#…...
电气网站建设/seo服务是什么
这是因为使用的是较新的TensorFlow版本,只需把TensorFlow换成其他低版本(如1.9.0)即可 pip install tensorflow1.8.0windows下查看已安装的tensorflow版本及路径,并且进行版本修改...
宝安西乡做网站/广告联盟怎么加入
一、安装包测试 1.1、关于反编译 目的是为了保护公司的知识产权和安全方面的考虑等,一些程序开发人员会在源码中硬编码一些敏感信息,如密码。而且若程序内部一些设计欠佳的逻辑,也可能隐含漏洞,一旦源码泄漏,安全隐患巨…...
有没有什么做统计的网站/seo优化的主要内容
蔡勒公式(根据日期计算出周几) 随便给一个日期,就能用这个公式推算出是星期几。不过,公式只适合于1582年10月15日之后的情形(当时的罗马教皇将恺撒大帝制订的儒略历修改成格里历,即今天使用的公历ÿ…...
门户网站开发价格/百度客户端电脑版下载
1 /// <summary> 2 /// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库 3 /// 1.首先在在项目中引用SQLDMO.DLL文件。 4 /// 2.在引用中的SQLDMO.DLL文件右击-->属性-->设置[嵌入互操作类型]为flash 5 /// </summary> 6 public static void DBBackup() 7 { …...
震泽做网站/宁波网站推广网站优化
1、TRACE 必须在调试模式下,才能输出信息。(是 debug 版本断点调试的模式下,不是运行模式下) 2、printf 在做DLL库的时候经常会通过printf打印一些调试信息,但是MFC项目引入后printf信息是无法输出到调试窗口的。 解决办法如下&a…...
重庆网站建设企业/爱站查询工具
前言对于分布式使用NginxTomcat实现负载均衡,最常用的均衡算法有IP_Hash、轮训、根据权重、随机等。不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因此会出现sessi…...