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 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.mzph.cn/web/54228.shtml

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

相关文章

C语言基础(7)之操作符(1)(详细介绍)

目录 1. 各种操作符介绍 1.1 操作符汇总表 2. 移位操作符 2.1 移位操作符知识拓展 —— 原码、反码、补码 2.2 移位操作符讲解 2.2.1 右移操作符 ( >> ) 2.2.2 左移操作符 ( << ) 3. 位操作符 3.1 & (按位与) 3.2 | (按位或) 3.3 ^ (按位异或) 3.4…

排序算法之——归并排序,计数排序

文章目录 前言一、归并排序1. 归并排序的思想2. 归并排序时间复杂度及空间复杂度3. 归并排序代码实现1&#xff09;递归版本2&#xff09;非递归版本 二、计数排序1. 计数排序的思想2. 计数排序的时间复杂度及空间复杂度3. 计数排序代码实现 总结&#xff08;排序算法稳定性&am…

【JavaEE】——线程池大总结

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c; 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 引入&#xff1a;问题引入 一&#xff1a;解决方案 1&#xff1a;方案一——协程/纤程 &#xff08;1…

【完-网络安全】Windows注册表

文章目录 注册表启动项及常见作用五个根节点常见入侵方式 注册表 注册表在windows系统的配置和控制方面扮演了一个非常关键的角色&#xff0c;它既是系统全局设置的存储仓库&#xff0c;也是每个用户的设置信息的存储仓库。 启动项及常见作用 快捷键 WinR打开运行窗口&#x…

【C++】C++基础

目录 一. C关键字(C98) 二、C的第一个程序 三、命名空间 3.1.namespace的价值 3.2.namespace的定义 3.2.命名空间使用 总结&#xff1a;在项目当中第一、第二种方法搭配使用&#xff0c;第三种冲突风险非常大&#xff0c;仅适合练习使用。 四、C输入&输出 五、缺省…

调试分析:[跳数度量]更改为[距离度量]后的 routing_bellmanford 算法

回顾复习2023年8月的《★修改Exata6.2源码&#xff1a;〔修改Bellmanford最短路径路由的衡量标准从【路由跳数】改为【“路由器节点间的物理距离”】&#xff0c;并动画演示〕》&#xff0c;VS2015调试Exata&#xff0c;跟踪调试修改后的[ routing_bellmanford.cpp ]源码&#…

k8s架构,从clusterIP到光电半导体,再从clusterIP到企业管理

clusterIP作为k8s中的服务&#xff0c; 也是其他三个服务的基础 ~]$ kubectl create service clusterip externalname loadbalancer nodeport 客户端的流量到service service分发给pod&#xff0c;pod由控制器自动部署&#xff0c;自动维护 那么问题是service的可用…

计算机网络期末复习真题(附真题答案)

前言&#xff1a; 本文是笔者在大三学习计网时整理的笔记&#xff0c;哈理工的期末试题范围基本就在此范畴内&#xff0c;就算真题有所更改&#xff0c;也仅为很基础的更改数值&#xff0c;大多跑不出这些题&#xff0c;本文包含简答和计算等大题&#xff0c;简答的内容也可能…

【RADARSAT Constellation Mission(RCM)卫星星座简介】

RADARSAT Constellation Mission&#xff08;RCM&#xff09;卫星星座是加拿大太空局&#xff08;CSA&#xff09;的下一代C波段合成孔径雷达&#xff08;SAR&#xff09;卫星星座&#xff0c;以下是对其的详细介绍&#xff1a; 一、基本信息 发射时间&#xff1a;2019年6月…

基于微信小程序的四六级词汇+ssm(lw+演示+源码+运行)

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;四六级词汇小程序被用户普遍使用&#xff0c;为方便用户能…

容器适配器-stack、queue、priority_queue和仿函数

目录 1.什么是适配器 2.deque 1.简单了解结构 2.deque的缺陷 3.为什么选择deque作为stack和queue的底层默认容器 3.stack&#xff08;栈&#xff09; 4.queue&#xff08;队列&#xff09; 5.仿函数 6.priority_queue&#xff08;优先级队列&#xff09;&#xff08;堆…

微信小程序map组件自定义气泡真机不显示

最近遇到一个需求需要使用uniapp的map自定义气泡 &#xff0c;做完之后发现在模拟器上好好的&#xff0c;ios真机不显示&#xff0c;安卓页数时好时不好的 一番查询发现是小程序的老问题了&#xff0c;网上的方法都试了也没能解决 后来看到有人说用nvue可以正常显示&#xff0c…

会议平台后端优化方案

会议平台后端优化方案 通过RTC的学习&#xff0c;我了解到了端对端技术&#xff0c;就想着做一个节省服务器资源的会议平台 之前做了这个项目&#xff0c;快手二面被问到卡着不知如何介绍&#xff0c;便有了这篇文章 分析当下机制 相对于传统视频平台&#xff08;SFU&#xff…

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是最常用的协议之一&#xff0c;广泛应用于各种网络应用&#xff0c;如网页浏览、文件传输和在线游戏等。然而&#xff0c;随着互联网的普及&#xff0c;小数据包的频繁传输成为一个不容忽视的问题。…

828华为云征文 | 云服务器Flexus X实例:向量数据库 pgvector 部署,实现向量检索

目录 一、什么是向量数据库 pgvector &#xff1f; 二、pgvector 部署 2.1 安装 Docker 2.2 拉取镜像 2.3 添加规则 三、pgvector 运行 3.1 运行 pgvector 3.2 连接 pgvector 3.3 pgvector 常见操作 四、总结 本篇文章通过 云服务器Flexus X实例 部署向量数据库 pgve…

Windows11系统下SkyWalking环境搭建教程

目录 前言SkyWalking简介SkyWalking下载Agent监控实现启动配置SkyWalking启动Java应用程序启动Elasticsearch安装总结 前言 本文为博主在项目环境搭建时记录的SkyWalking安装流程&#xff0c;希望对大家能够有所帮助&#xff0c;不足之处欢迎批评指正&#x1f91d;&#x1f91…

计算机毕业设计之:音乐媒体播放及周边产品运营平台(源码+文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

Json 在线可视化工具,分享几个

文章目录 1.json.cn2.json4u.cn3.jsonvisual.com4.jsoncrack5.altearius.github.io6.json.wanvb.com 前序&#xff1a;本文是对多种 Json 在线可视化工具 的介绍、分享。Json官网 https://www.json.org/json-en.html 个人比较中意第四款&#xff1a; https://jsoncrack.com/ed…

测试用例的进阶二

1. 按开发阶段划分 1.1 测试金字塔 从上到下&#xff0c;对于测试人员代码就是要求越来越低&#xff1b; 从下到上&#xff0c;越来越靠近用户&#xff1b; 从下到上&#xff0c;定位问题的成本越来越高&#xff1b; 1.2 单元测试(Unit Testing) 单元测试是对软件组成单元进…

uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource

我把图片放在assets里面页面通过相对路径引入。结果一直报错。 最后我把图片放在static文件夹下面。然后修改路径指向static就可以了 或者是我们必须先import 这个图片然后在使用 import banner1 from ../../assets/images/banner/banner1.png; <image :src"banner…