【JavaScript 算法】堆排序:优先队列的实现

在这里插入图片描述

🔥 个人主页:空白诗

在这里插入图片描述

文章目录

    • 一、算法原理
      • 堆的定义
      • 堆排序的步骤
    • 二、算法实现
      • 构建最大堆
      • 注释说明:
    • 三、应用场景
    • 四、总结

在这里插入图片描述

堆排序(Heap Sort)是一种基于堆数据结构的排序算法,具有较好的时间复杂度表现。堆是一种特殊的完全二叉树,分为最大堆和最小堆。堆排序通过构建最大堆或最小堆来实现排序过程。本文将详细介绍堆排序算法的原理、实现及其应用。


一、算法原理

堆排序的基本思想是将待排序的数组构建成一个最大堆或最小堆,然后通过堆的删除操作将堆顶元素逐个取出,得到一个有序序列。

堆的定义

  • 最大堆:每个节点的值都大于或等于其子节点的值。
  • 最小堆:每个节点的值都小于或等于其子节点的值。

堆排序的步骤

  1. 构建最大堆:将数组重新组织成一个最大堆。
  2. 交换堆顶元素与末尾元素:将堆顶元素(最大值)与末尾元素交换,将最大值移到数组末尾。
  3. 调整堆:重新调整堆,保持最大堆性质。
  4. 重复步骤2和3,直到堆的大小为1,排序完成。
开始
构建最大堆
从最后一个非叶子节点开始调整堆
调整堆
是否调整完所有节点?
交换堆顶元素与末尾元素
调整堆
堆大小是否为1?
结束

二、算法实现

构建最大堆

/*** 调整堆* @param {number[]} arr - 数组* @param {number} len - 堆的有效大小* @param {number} i - 当前节点的索引*/
function heapify(arr, len, i) {let largest = i; // 初始化当前节点为最大值const left = 2 * i + 1; // 左子节点索引const right = 2 * i + 2; // 右子节点索引// 如果左子节点存在且大于当前节点,则更新最大值if (left < len && arr[left] > arr[largest]) {largest = left;}// 如果右子节点存在且大于当前节点,则更新最大值if (right < len && arr[right] > arr[largest]) {largest = right;}// 如果最大值不是当前节点,则交换并继续调整堆if (largest !== i) {[arr[i], arr[largest]] = [arr[largest], arr[i]];heapify(arr, len, largest);}
}/*** 堆排序算法* @param {number[]} arr - 待排序的数组* @return {number[]} - 排序后的数组*/
function heapSort(arr) {const len = arr.length;// 构建最大堆for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {heapify(arr, len, i);}// 逐个将堆顶元素移到末尾,然后调整堆for (let i = len - 1; i > 0; i--) {[arr[0], arr[i]] = [arr[i], arr[0]]; // 交换堆顶元素与末尾元素heapify(arr, i, 0); // 调整堆}return arr;
}// 示例
const arr = [3, 19, 1, 14, 8, 7];
console.log(heapSort(arr)); // 输出: [1, 3, 7, 8, 14, 19]

注释说明:

  1. 调整堆

    • heapify(arr, len, i):调整堆,使其保持最大堆性质,接受数组、堆的有效大小和当前节点的索引作为参数。
    • let largest = i;:初始化当前节点为最大值。
    • const left = 2 * i + 1; const right = 2 * i + 2;:计算左、右子节点的索引。
    • if (left < len && arr[left] > arr[largest]) largest = left;:如果左子节点大于当前节点,更新最大值。
    • if (right < len && arr[right] > arr[largest]) largest = right;:如果右子节点大于当前节点,更新最大值。
    • if (largest !== i) [arr[i], arr[largest]] = [arr[largest], arr[i]]; heapify(arr, len, largest);:如果最大值不是当前节点,则交换并继续调整堆。
  2. 堆排序

    • heapSort(arr):堆排序算法,接受待排序的数组作为参数,返回排序后的数组。
    • const len = arr.length;:获取数组长度。
    • for (let i = Math.floor(len / 2) - 1; i >= 0; i--) heapify(arr, len, i);:从最后一个非叶子节点开始构建最大堆。
    • for (let i = len - 1; i > 0; i--) [arr[0], arr[i]] = [arr[i], arr[0]]; heapify(arr, i, 0);:逐个将堆顶元素移到末尾,然后调整堆。

三、应用场景

  1. 优先队列:堆可以实现优先队列,优先级最高的元素总是位于堆顶。
  2. 任务调度:堆可以用于任务调度,将优先级最高的任务最先处理。
  3. 实时数据流排序:在实时数据流中,使用堆可以高效地维护一个有序的数据集。

四、总结

堆排序是一种基于堆数据结构的高效排序算法,通过构建最大堆或最小堆,利用堆的特性实现排序过程。理解和掌握堆排序算法,可以有效解决优先队列、任务调度和实时数据流排序等问题。


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

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

相关文章

Electron案例解析——切换主题颜色的案例

效果图 核心 Electron的 nativeTheme.themeSource属性&#xff0c;值是string。有三个参数&#xff1a;system, light 和 dark&#xff0c;用来覆盖、重写Chromium内部的相应的值 Election的api描述值nativeTheme.themeSource被用来覆盖、重写Chromium内部的相应的值system, …

邮件安全篇:邮件传输加密(SSL/TLS or STATRTTLS)

1. 前言 使用过邮件客户端的同学一定见过下面这张图。这是客户端账号配置界面&#xff0c;里面有SSL、STARTTLS选项。刚接触邮件客户端的同学肯定会有这些疑问&#xff1a;什么是SSL&#xff1f;什么是STARTTLS&#xff1f;两者有什么区别&#xff1f;具体该如何选择呢&#x…

Stable Diffusion 使用详解(2)---- 图生图原理,操作,参数

目录 背景 图生图原理 基本原理 1. 扩散模型基础 2. 图生图的具体流程 3. 关键技术点 4. 应用实例 CLIP 原理 1.基本概念 2. 核心特点 使用及参数 随机种子 重绘幅度 图像宽高 采样方法 1. DPM&#xff08;扩散概率模型&#xff09; 2. SDE&#xff08;随机微…

能源化工5G防爆终端能给行业带来什么重要作用?

在能源化工领域&#xff0c;5G防爆终端的引入无疑为行业带来了革命性的变革与重要作用。这些集成了先进5G通信技术和防爆设计的高端设备&#xff0c;不仅提升了生产作业的安全性&#xff0c;还极大地增强了运营效率与智能化水平。 高速、低延迟的5G网络为防爆终端提供了前所未有…

机器人控制:物理人机交互控制中的不稳定性因素及其解决思路

机器人控制&#xff1a;物理人机交互控制中的不稳定性因素及其解决思路 物理人机交互控制中的不稳定性是指在机器人或相关物理系统与人类进行交互时&#xff0c;系统行为表现出的一种非预期、不可控或难以预测的动态特性。这种不稳定性可能源于多个方面&#xff0c;包括但不限于…

SPA Fiori开发实战课程(一)

前言 由于工作需要&#xff0c;对Fiori的开发有了一些具体实践&#xff0c;所以做一些记录和总结。 准备工作 1. 对前端有一定的了解&#xff0c;熟悉Node.js&#xff0c;Vue等前端服务器和基础框架。 2. 后端使用ABAP系统。 3. 使用Visual Studio Code进行开发。 工程搭建 打…

基于springboot+vue+uniapp的开放实验室预约管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

通信流程:https【SSL/TLS】,git仓库【https/SSH】,蓝牙【面对面快传/AirDrop】

目录 HTTPS HTTP&#xff08;80端口&#xff09; SSL/TLS协议&#xff08;传输层&#xff0c;443端口&#xff09; 密文传输&#xff1a;SSL的后续版本TLS TLS1.2握手 1.摘要算法(散列函数 Hash Function)&#xff1a;验证信息的完整性&#xff0c;不可逆 第三方认证 引…

弹性网络回归(Elastic Net Regression)

弹性网络回归&#xff08;Elastic Net Regression&#xff09;的详细理论知识推导 理论背景 弹性网络回归结合了岭回归&#xff08;Ridge Regression&#xff09;和Lasso回归&#xff08;Lasso Regression&#xff09;的优点&#xff0c;通过引入两个正则化参数来实现特征选择…

【Android】ConstrainLayout约束布局基本操作

文章目录 介绍约束条件添加方式外边距设置删除方式 添加约束条件父级位置对齐方式基线对齐引导线约束屏障约束 约束偏差使用链控制线性组 介绍 约束布局ConstraintLayout是 Android Studio 2.3 起创建布局后的默认布局 主要是为了解决布局多层嵌套问题&#xff0c;以灵活的方式…

抖音/腾讯/百度ocpm深度回传如何操作?广告投放双出价的投放技巧?

要实现抖音、腾讯和百度的OCPM&#xff08;Optimized Cost Per Mille&#xff09;深度回传&#xff0c;可以通过借助第三方平台&#xff0c;例如&#xff08;转化宝&#xff09;实现广告数据精准回传&#xff0c;如此之外&#xff0c;在广告投放过程中还需要注重这些方面。 转化…

ros笔记02--从零体验ros2中的服务通信方式

ros笔记02--从零体验ros2中的服务通信方式 介绍创建步骤注意事项说明 介绍 在ROS 2中&#xff0c;服务指的是远程过程调用&#xff0c;client调用server&#xff0c;server节点收到数据后计算出结果并返回给client. 服务通常期望能快速返回&#xff0c;因此不应当用于处理长时…

深度学习落地实战:大模型生成图片

前言 大家好&#xff0c;我是机长 本专栏将持续收集整理市场上深度学习的相关项目&#xff0c;旨在为准备从事深度学习工作或相关科研活动的伙伴&#xff0c;储备、提升更多的实际开发经验&#xff0c;每个项目实例都可作为实际开发项目写入简历&#xff0c;且都附带完整的代…

TypeScript 教程(十):项目配置、代码质量与前端框架集成

目录 前言回顾类型声明文件与异步编程1. tsconfig.json 高级配置a. 基本配置b. 高级配置选项 2. 使用 Webpack 构建 TypeScript 项目a. 安装依赖b. 配置 Webpack 3. 使用 Babel 编译 TypeScripta. 安装依赖b. 配置 Babelc. 配置 Webpack 使用 Babel 4. 使用 ESLint 和 TSLinta.…

复杂网络的任意子节点的网络最短距离

复杂网络的任意子节点的网络最短距离 题目要求介绍 本文算法测试用的数据集为空手道俱乐部&#xff0c;其中空手道俱乐部的数据集可通过这个链接进行下载•http://vlado.fmf.uni-lj.si/pub/networks/data/Ucinet/UciData.htm#zachary 摘要 本文旨在解决复杂网络中任意子节点…

Godot学习笔记2——GDScript变量与函数

目录 一、代码编写界面 二、变量 三、函数 四、变量的类型 Godot使用的编程语言是GDS&#xff0c;语法上与python有些类似。 一、代码编写界面 在新建的Godot项目中&#xff0c;点击“创建根节点”中的“其他节点”&#xff0c;选择“Node”。 点击场景界面右上角的绿色…

前端Vue组件化实践:自定义发送短信验证码弹框组件

在前端开发中&#xff0c;随着业务逻辑的日益复杂和交互需求的不断增长&#xff0c;传统的整体式开发方式逐渐暴露出效率低下、维护困难等问题。为了解决这些问题&#xff0c;组件化开发成为了一种流行的解决方案。通过组件化&#xff0c;我们可以将复杂的系统拆分成多个独立的…

LeetCode 860柠檬水找零(贪心算法)/406根据身高重建队列(贪心算法)

1. 柠檬水找零 思路分析 只需要维护三种金额的数量&#xff0c;5&#xff0c;10和20。 有如下三种情况&#xff1a; 情况一&#xff1a;账单是5&#xff0c;直接收下。情况二&#xff1a;账单是10&#xff0c;消耗一个5&#xff0c;增加一个10情况三&#xff1a;账单是20&am…

使用Java -jar运行就jar包时报异常:org.yaml.snakeyaml.error.YAMLException异常

Java运行就 .jar包时出现的 YAMLException 异常 我在本地环境测试时&#xff0c;使用 java -jar 命令运行 Java 可执行 .jar 包时&#xff0c;遇到了 org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length 1 异常&#xff1b;这…

关于集成网络变压器的RJ45网口

集成网络变压器的RJ45网口是一种将网络变压器与RJ45接口集成在一起的网络连接解决方案。这种集成设计具有多项优势&#xff0c;使其在现代网络设备中得到广泛应用。 优势与特点 1. **空间节省**&#xff1a;集成设计减少了组件数量和连接线缆长度&#xff0c;有助于节省设备内…