当前位置: 首页 > news >正文

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 归并排序特点

  1. 分治思想: 归并排序采用分治策略,将复杂问题分解为简单子问题
  2. 稳定性: 归并排序是稳定的排序算法
  3. 时间复杂度: 无论最好、最坏还是平均情况,时间复杂度都是O(nlogn)
  4. 空间复杂度: 需要额外的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. 归并排序的优点

  1. 稳定性好: 归并排序是稳定的排序算法
  2. 时间复杂度稳定: 无论最好、最坏还是平均情况,时间复杂度都是O(nlogn)
  3. 适合外部排序: 当数据量很大,无法一次性加载到内存时,归并排序特别有用

5. 归并排序的缺点

  1. 空间复杂度高: 需要额外的O(n)空间
  2. 对于小规模数据,不如插入排序等简单算法效率高

总结

归并排序就像是一个团队合作的游戏。面对复杂的问题,先将其分解成小问题,各自解决后再合并结果。这种"分而治之"的思想不仅在排序算法中有用,在我们日常解决问题时也常常能派上用场。

归并排序的稳定性和时间复杂度的优势,使它在处理大规模数据时表现出色。特别是在外部排序中,当数据量大到无法一次性加载到内存时,归并排序的思想就显得尤为重要。

没有一种算法是完美的,归并排序的空间复杂度相对较高,在某些内存受限的场景中可能成为一个问题,对于小规模数据,它不如一些更简单的算法高效。因此了解每种算法的特点和适用场景,在实际应用中做出最佳选择。

喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!

下期预告: 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&#xff08;Mechanisms Of Action&#xff0c;作用机理&#xff09; 过去&#xff0c;在药物投入到临床使用之前&#xff0c;它的生物学机理往往未被研究透彻。如今&#xff0c;随着技术的发展&#xff0c;一种新药物…...

基础岛第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虚拟环境允许你为每个独立的项目创建一个隔离的环境&#xff0c;这样每个项目都可以拥有自己的一套Python安装包和依赖&#xff0c;不会互相影响。实际使用中&#xff0c;可以在vscode或pycharm中使用虚拟环境。 1.创建虚拟环境的方法&#xff1a; …...

chatGPT对我学术写作的三种帮助

chatGPT对我学术写作的三种帮助 概述提高学术写作水平大模型选择概述上下文以提供精确的指令 提升同行评审优化编辑反馈 概述 从生成式人工智能中获得的价值并非来自于技术本身盲目地输出文本&#xff0c;而是来自于与工具的互动&#xff0c;并利用自身的专业知识来完善它所生…...

【PostgreSQL 】入门篇——支持的各种数据类型介绍,包括整数、浮点数、字符串、日期、JSON、数组等

1. 整数类型 1.1 SMALLINT 描述&#xff1a;用于存储小范围的整数值。大小&#xff1a;2 字节范围&#xff1a;-32,768 到 32,767使用场景&#xff1a;适合存储小型计数器、状态码等。示例&#xff1a; CREATE TABLE status_codes (id SMALLINT PRIMARY KEY,description TEX…...

野火STM32F103VET6指南者开发板入门笔记:【1】点亮RGB

硬件介绍 提示&#xff1a;本文是基于野火STM32F103指南者开发板所写例程&#xff0c;其他开发板请自行移植到自己的工程项目当中即可。 RGB-LEDPin引脚&#xff1a;低电平-点亮&#xff0c;高电平-熄灭REDPB5GREENPB0BLUEPB1 文章目录 硬件介绍软件介绍&#xff1a;结构体方式…...

数据工程师岗位常见面试问题-3(附回答)

数据工程师已成为科技行业最重要的角色之一&#xff0c;是组织构建数据基础设施的骨干。随着企业越来越依赖数据驱动的决策&#xff0c;对成熟数据工程师的需求会不断上升。如果您正在准备数据工程师面试&#xff0c;那么应该掌握常见的数据工程师面试问题&#xff1a;包括工作…...

强大的JVM监控工具

介绍 在生产环境中&#xff0c;经常会遇到各种各样奇葩的性能问题&#xff0c;所以掌握最基本的JVM命令行监控工具还是很有必要的 名称主要作用jps查看正在运行的Java进程jstack打印线程快照jmap导出堆内存映像文件jstat查看jvm统计信息jinfo实时查看和修改jvm配置参数jhat用…...

python 实现点的多项式算法

点的多项式算法介绍 点的多项式算法通常指的是通过一组点&#xff08;即数据点&#xff0c;通常包括自变量和因变量的值&#xff09;来拟合一个多项式函数的方法。这种方法在数值分析、统计学、机器学习等领域中非常常见。下面是一些常见的多项式拟合算法&#xff1a; 1. 最小…...

Pikachu-暴力破解-验证码绕过(on client)

访问页面&#xff0c; 从burpsuite 上看到返回的源代码&#xff1b; 验证码生成时通过 createCode 方法生成&#xff0c;在前端页面生成&#xff1b; 同时也是在前端做的校验&#xff1b; 直接验证&#xff1b;F12 -- 网络&#xff0c;随便输入个账号、密码、验证码&#xff0…...

【Spring】Bean 的生命周期:从实例化到销毁

实例化阶段&#xff1a; Bean的实例化是通过反射创建的。Spring根据Component、Bean或者XML中的<bean>元素配置&#xff0c;来确定要创建的Bean。 属性赋值阶段&#xff1a; 实例化完成后&#xff0c;Spring会进行依赖注入。包括将属性值注入到Bean的字段中&#xff0c;…...

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 专用术语 实体 实体是指任何可以发送或接收信息的硬件或软件进程 对等实体是指通信双方处于相同层次中的实体&#xff0c;如通信双方应用层的浏览器进程和 Web 服务器进程。 协…...

Rust的前端Tauri编程-基于JS框架的初步探索

上次的项目做完后&#xff0c;有一项遗憾&#xff0c;没有返回结果&#xff0c;而结果是一个html表格&#xff0c;我想用html直接在窗口显示&#xff0c;这时发现R里面包括slint没有很直接的方法&#xff0c;直接弹出浏览器有点太简单没有挑战。这是就被推送了他的竞争对手&…...

【Flume Kafaka实战】Using Kafka with Flume

一 目标 在Cloudera Manager中创建两个Flume的Agent&#xff0c;Agent1从local file中获取内容&#xff0c;写入到kafka的队列中。Agent2以Agent1的sink作为source&#xff0c;将数据从kafka中读取出来&#xff0c;写入到HDFS中。 二 实战 2.1 Kafka Sink 第一步&#xff0…...

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 &#xff0c;随便输入点内容&#xff0c;都能保存下来&#xff1b;刷新后也不会丢失&#xff1b;输入特殊字符&#xff0c;也能原样返回&#xff1b; 查看代码&#xff0c;也可以看到输出结果直接原路返回&#xff0c;不做处理 构造payload <script>alert(1)…...

媲美GPT-4o mini的小模型,Meta Llama 3.2模型全面解读!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...