TypeScript 算法手册【快速排序】

news2024/11/16 1:16:53

文章目录

    • 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 quickSort(arr: number[]): number[] {
  if (arr.length <= 1) return arr;

  const pivot = arr[Math.floor(arr.length / 2)];
  const left = arr.filter(x => x < pivot);
  const middle = arr.filter(x => x === pivot);
  const right = arr.filter(x => x > pivot);

  return [...quickSort(left), ...middle, ...quickSort(right)];
}

1.2 快速排序特点

  1. 分治思想:快速排序采用分治策略,将复杂问题分解为简单子问题
  2. 原地排序:快速排序可以在原数组上进行,不需要额外的存储空间
  3. 时间复杂度:平均情况下为O(nlogn),最坏情况下为O(n^2)
  4. 不稳定性:快速排序是不稳定的排序算法

2. 快速排序步骤过程拆解

2.1 选择基准元素

const pivot = arr[Math.floor(arr.length / 2)];

这就像园丁从花园中间随机选择一株花作为参考,这株花将成为我们划分其他花的标准。

2.2 划分数组

const left = arr.filter(x => x < pivot);
const middle = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);

这个步骤就像园丁将其他花分成三组:比参考花"矮"的、与参考花一样高的、比参考花"高"的。在实际的快速排序实现中,我们通常会使用双指针法在原地完成这个过程,就像园丁在花园里来回走动,将花朵移到合适的位置。

2.3 递归排序

return [...quickSort(left), ...middle, ...quickSort(right)];

这个步骤就像园丁对"矮"组和"高"组的花朵重复之前的过程,直到所有的花都被正确地排列在花园里。

3. 快速排序的优化

3.1 三数取中法选择基准

function medianOfThree(arr: number[], left: number, right: number): number {
  const mid = Math.floor((left + right) / 2);
  if (arr[left] > arr[mid]) [arr[left], arr[mid]] = [arr[mid], arr[left]];
  if (arr[left] > arr[right]) [arr[left], arr[right]] = [arr[right], arr[left]];
  if (arr[mid] > arr[right]) [arr[mid], arr[right]] = [arr[right], arr[mid]];
  return mid;
}

function quickSortOptimized(arr: number[], left: number = 0, right: number = arr.length - 1): number[] {
  if (left < right) {
    const pivotIndex = medianOfThree(arr, left, right);
    const pivotNewIndex = partition(arr, left, right, pivotIndex);
    quickSortOptimized(arr, left, pivotNewIndex - 1);
    quickSortOptimized(arr, pivotNewIndex + 1, right);
  }
  return arr;
}

function partition(arr: number[], left: number, right: number, pivotIndex: number): number {
  const pivot = arr[pivotIndex];
  [arr[pivotIndex], arr[right]] = [arr[right], arr[pivotIndex]];
  let storeIndex = left;
  for (let i = left; i < right; i++) {
    if (arr[i] < pivot) {
      [arr[i], arr[storeIndex]] = [arr[storeIndex], arr[i]];
      storeIndex++;
    }
  }
  [arr[storeIndex], arr[right]] = [arr[right], arr[storeIndex]];
  return storeIndex;
}

这个优化版本就像园丁不是随机选择参考花,而是从花园的开始、中间和结尾各选一朵花,然后选择这三朵花中"中间"高度的那朵作为参考,这样可以减少选到"最高"或"最矮"的花作为参考的概率,从而提高排序效率。

3.2 插入排序与快速排序结合

function hybridQuickSort(arr: number[], left: number = 0, right: number = arr.length - 1, threshold: number = 10): number[] {
  if (right - left + 1 <= threshold) {
    return insertionSort(arr, left, right);
  }
  
  if (left < right) {
    const pivotIndex = medianOfThree(arr, left, right);
    const pivotNewIndex = partition(arr, left, right, pivotIndex);
    hybridQuickSort(arr, left, pivotNewIndex - 1, threshold);
    hybridQuickSort(arr, pivotNewIndex + 1, right, threshold);
  }
  return arr;
}

function insertionSort(arr: number[], left: number, right: number): number[] {
  for (let i = left + 1; i <= right; i++) {
    let current = arr[i];
    let j = i - 1;
    while (j >= left && arr[j] > current) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = current;
  }
  return arr;
}

这个优化版本就像园丁在整理花园时,发现某一小片区域的花朵数量少于某个阈值(比如10朵)时,直接用更简单的方法来排列这些花。这样可以减少整理的复杂度,提高整体的效率。

案例代码和动态图

const array = [38, 27, 43, 3, 9, 48, 10];
const sortedArray = quickSort(array);
console.log(sortedArray); // [3, 9, 10, 27, 38, 43, 48]

在这里插入图片描述

4. 快速排序的优点

  1. 高效性:在平均情况下,快速排序是所有同数量级(O(nlogn))排序算法中最快的
  2. 原地排序:快速排序可以在原数组上进行,不需要额外的存储空间
  3. 缓存友好:快速排序的数据访问模式对缓存友好,这使得它在实际应用中表现优秀

5. 快速排序的缺点

  1. 不稳定性:快速排序是不稳定的排序算法
  2. 最坏情况性能:在最坏情况下(已经排序的数组),时间复杂度退化到O(n^2)
  3. 对小规模数据,不如插入排序等简单算法效率高

总结

快速排序就像是园丁整理一大片杂乱的花园。它告诉我们,面对一大片混乱的花朵,可以通过选择一株参考花,将花园分成两部分,然后逐步整理。这种"分而治之"的思想不仅在整理花园中有用,在我们日常解决复杂问题时也常常能派上用场。

快速排序的高效性和原地排序的特性,使它在实际应用中表现出色。特别是在处理大规模数据时,快速排序常常是首选的算法。然而,它的不稳定性和在某些特殊情况下的性能退化,也提醒我们在选择算法时需要考虑具体的应用场景。

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

下期预告: TypeScript 算法手册 - 计数排序

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

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

相关文章

二分查找算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 二分查找算法的介绍 704. 二分查找 34. 在排序数组中查找元素的第一个和 最后一个位置 35. 搜索插入位置 69. x的平…

10-指针和多维数组

多维数组&#xff0c;本质上是数组的数组&#xff1a; 一、多维数组&#xff1a; int B[2][3] int(*P)[3] B;Print B //400 Print *B; //400 Print B[0] //400 Print &B[0][0] // 400B[i][j] *(B[i]j) *(*(Bi)j); int C[3][2][2] int(*p)[2][2] C; Print C //800 Prin…

大数据开发--1.1大数据概论

目录 一.大数据的概念 什么是大数据&#xff1f; 二. 大数据的特点 三. 大数据应用场景 四. 大数据分析业务步骤 大数据分析的业务流程&#xff1a; 五.大数据职业规划 职业方向 岗位技术要求 六. 大数据学习路线 一.大数据的概念 什么是大数据&#xff1f; 数据 世界…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第十六章 Linux 第一个程序 HelloWorld

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

LC记录二:丑数专题,一文秒解丑数3题

文章目录 263.丑数1264.丑数21201.丑数3 263.丑数1 https://leetcode.cn/problems/ugly-number/description/ 简单题&#xff0c;丑数只包含质因子2、3、5。所以直接使用 n 循环 除 2 3 5最后判断结果是否等于1即可。 代码&#xff1a; class Solution {public boolean isUg…

01_SQLite

文章目录 ** SQLite 存储各类和数据类型 **** SQLite 五种亲缘类型** SQLite 创建数据表删除数据表插入数据信息从数据表中获取数据&#xff0c;以结果表的形式返回数据&#xff08;结果集&#xff09;updatedistinctorder bygroup byhaving触发器删除一个触发器&#xff08;tr…

计网问答大题(期末复习)

计网总结笔记 概述 互联网的 2 个重要基本特点&#xff1a;连通性&#xff0c;资源共享 从互联网的工作方式上看&#xff0c;可以划分为两大块&#xff1a; •边缘部分&#xff1a; 由所有连接在互联网上的主机组成&#xff0c;由用户直接使用&#xff0c;用来进行通信&…

并查集【数据结构与算法】【C语言版-笔记】

目录 一、需求分析二、并查集三、代码实现3.1 Find函数3.2 Union函数3.3 优化13.4 终极优化2---压缩策略 一、需求分析 假设有n个互不相交的集合 ◼问题1&#xff1a;给定某个集合中的一个元素&#xff0c;查找该元素属于哪个集合&#xff1f; ◼问题2&#xff1a;如何合并两个…

建筑业挂靠行为的防范建议

在建筑行业中&#xff0c;挂靠行为的普遍存在给许多企业带来了法律风险和信誉风险。为了防范这些风险&#xff0c;企业需要采取一系列有效的措施。 一、加强资质管理 企业应当通过合法途径获取和提升自身的资质等级&#xff0c;避免因资质不足而产生挂靠的需求。加强资质管理是…

【半导体物理基础】第1章 半导体中的电子状态和能带,晶格结构,有效质量

目录 1.1 半导体晶格结构和结合性质 固体的种类 典型晶体 元素半导体 几种晶胞结构 晶向指数与晶面 半导体的晶体结构 金刚石结构 金刚石结构的结晶学原胞 硅、锗相关参数 硅、锗相关参数计算 闪锌矿结构 纤锌矿结构 氯化钠型结构 1.2 半导体中的电子状态和能带…

Study-Oracle-10-ORALCE19C-RAC集群搭建

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。 ORACLE --RAC 搭建理念:准备工作要仔细,每个参数及配置都到仔细核对。环境准备完成后,剩下的就是图像化操作,没啥难度,所以图形化操作偷懒不续写了。 一、硬件信息及配套软件 1、硬件设置 RAC…

客厅落地台灯怎么摆放?五款客厅落地台灯款式分享

客厅落地台灯怎么摆放&#xff1f;客厅落地台灯是提升光线环境在室内光线质量的关键设备。但如果不慎购买到低质量的客厅落地台灯&#xff0c;可能会导致光线效果不佳&#xff0c;进而影响视力健康。因此&#xff0c;挑选一个可靠的品牌至关重要。那么&#xff0c;客厅落地台灯…

ubuntu 18.04 cuda 11.01 gpgpu-sim 裸机编译

1&#xff0c;环境 ubuntu 18.04 x86_64 cuda 11.01 gpgpu-sim master commit 90ec3399763d7c8512cfe7dc193473086c38ca38 2&#xff0c;预备环境 一个比较新的 ubuntu 18.04&#xff0c;为了迎合 cuda 11.01 的版本需求 安装如下软件&#xff1a; sudo apt-get instal…

Thinkphp/Laravel基于vue的的出版社书籍阅读管理系统

目录 技术栈和环境说明具体实现截图设计思路关键技术课题的重点和难点&#xff1a;框架介绍数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取 技术栈和环境说明 采用PHP语言开发&#xff0c;开发环境为phpstudy 开发工具notepad并使用MYSQL数据库…

netty之NettyClient半包粘包处理、编码解码处理、收发数据方式

前言 Netty开发中&#xff0c;客户端与服务端需要保持同样的&#xff1b;半包粘包处理&#xff0c;编码解码处理、收发数据方式&#xff0c;这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了&#xff1b;半包粘包、编码解码等&#xff0c;为此在本章节我们…

Pikichu-xss实验案例-通过xss获取cookie

原理图&#xff1a; pikachu提供了一个pkxss后台&#xff1b; 该后台可以把获得的cookie信息显示出来&#xff1b; 查看后端代码cookie.php&#xff1a;就是获取cookie信息&#xff0c;保存起来&#xff0c;然后重定向跳转到目标页面&#xff1b;修改最后从定向的ip&#xff0…

PTH 实验

1. 实验网络拓扑 kali: 192.168.72.128win2008: 192.168.135.129 192.168.72.139win7: 192.168.72.149win2012:(DC) 192.168.72.131 2. EXPLOIT 0x0. NTLM hash计算脚本 python3 -c import hashlib,binascii; print (binascii.hexlify(hashlib.new("md4", "…

基于51单片机的3路电压测量-proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1PG2vzudc1QKHGSBfjPF0eQ 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…

Leecode热题100-84.柱状图中的最大矩形

给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&#xff1a;最大的矩形为图…

SQL SERVER 从嫌弃存储到爱上存储过程我给存储过程开发了版本控制工具和远程调试功能...

优缺点 SQL SERVER 爱上存储过程我给存储过程开发了版本控制工具和远程调试功能 先说说 存储过程的优缺点吧存储过程的优点 提高执行效率&#xff1a;存储过程是预编译的&#xff0c;执行速度较快&#xff0c;减少了网络传输量。 减少开发工作量&#xff1a;存储过程可以将复杂…