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

news2024/9/20 12:41:45

在这里插入图片描述

🔥 个人主页:空白诗

在这里插入图片描述

文章目录

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

在这里插入图片描述

堆排序(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.coloradmin.cn/o/1937437.html

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

相关文章

uniapp中给data中的变量赋值报错

排查了一上午&#xff0c;原本以为是赋值的这个变量有一个键名是空字符串的问题&#xff0c;后来发现是因为在data中定义变量是写的是{}&#xff0c;如果写成null就不会报错了&#xff0c;具体原因不清楚为什么

jmeter部署

一、windows环境下部署 1、安装jdk并配置jdk的环境变量 (1) 安装jdk jdk下载完成后双击安装包&#xff1a;无限点击"下一步"直到完成&#xff0c;默认路径即可。 (2) jdk安装完成后配置jdk的环境变量 找到环境变量中的系统变量&#xff1a;此电脑 --> 右键属性 …

java Selenium,定位 伪元素.UI自动化

Java中&#xff0c;要获取这个表单字段前面的必填标识星号“*”&#xff0c;因为是用的伪元素&#xff0c;无法直接通过常规定位获取字符&#xff0c;需要用到 JavascriptExecutor。 import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import or…

K8S实战进阶

title ‘K8S实战进阶’ date 2024-04-02T16:57:3608:00 draft true 一、搭建Kubernetes集群 1.1 搭建方案 1.1.1 minikube minikube 是一个工具&#xff0c; 能让你在本地运行 Kubernetes。 minikube 在你的个人计算机&#xff08;包括 Windows、macOS 和 Linux PC&…

【座舱域控器】座舱域的通信方案

座舱域的通信方案 座舱域控器作为整车的几大域控器之一&#xff0c;提供驾驶娱乐的功能。比如中控、副驾、仪表、HUD等。 就座舱来说&#xff0c;座舱域控制器以及MCU&#xff0c;加上一系列的硬件外设。以及再此硬件之上的软件系统&#xff0c;构成了整个座舱系统。 同时&…

【JavaScript 算法】双指针法:高效处理数组问题

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、算法原理二、算法实现示例问题1&#xff1a;两数之和 II - 输入有序数组示例问题2&#xff1a;反转字符串中的元音字母注释说明&#xff1a; 三、应用场景四、总结 双指针法&#xff08;Two Pointer Technique&#xff…

全面了解不同GPU算力型号的价格!

这两年人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、深度学习和高性能计算&#xff08;HPC&#xff09;领域的快速发展&#xff0c;GPU算力已成为不可或缺的资源。企业、研究机构乃至个人开发者越来越依赖于GPU加速计算来处理大规模数据集和复杂模…

数据实时获取方案之Flink CDC

目录 一、方案描述二、Flink CDC1.1 什么是CDC1.2 什么是Flink CDC1.3 其它CDC1.4 FlinkCDC所支持的数据库情况 二、使用Pipeline连接器实时获取数据2.1 环境介绍2.2 相关版本信息2.3 详细步骤2.3.1 实时获取MySQL数据并发送到Kafka2.3.2 实时获取MySQL数据并同步到Doris数据库…

240718_使用Labelme制作自己的图像分割数据集

240718_使用Labelme制作自己的图像分割数据集 从目标检测入门的朋友们可能更熟悉的是LabelImg&#xff0c;这里要注意做好区分&#xff0c;LabelImg和Labelme不是一个东西&#xff0c;如下经典图&#xff1a; &#xff08;a&#xff09;图像分类&#xff08;目标检测&#xff…

机器学习·概率论基础

概率基础 这部分太简单&#xff0c;直接略过 条件概率 独立性 独立事件A和B的交集如下 非独立事件 非独立事件A和B的交集如下 贝叶斯定理 先验 事件 后验 在概率论和统计学中&#xff0c;先验概率和后验概率是贝叶斯统计的核心概念 简单来说后验概率就是结合了先验概率的前提…

院内影像一体化平台PACS源码,C#语言的PACS/RIS系统,二级医院应用案例

全院级PACS系统源码&#xff0c;一体化应用系统整合&#xff0c;满足放射、超声、内窥镜中心、病理、检验等多个科室的工作流程和需求&#xff0c;为不同科室提供专业的解决方案&#xff0c;实现了全院乃至区域内信息互联互通、数据统一存储与管理等功能&#xff0c;做到以病人…

微软研发致胜策略 05:进度狂

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1994 年发布。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Debugging the Development Process》&#xff0c;这本书详细阐述了软件开发过程中的常见问题及其解决方案&a…

免费视频批量横转竖

简介 视频处理器 v1.3 是一款由是貔貅呀开发的视频编辑和处理工具&#xff0c;提供高效便捷的视频批量横转竖&#xff0c;主要功能&#xff1a; 导入与删除文件&#xff1a;轻松导入多个视频文件&#xff0c;删除不必要的文件。暂停与继续处理&#xff1a;随时暂停和继续处理。…

大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBaseRedis &#xff08;正在更新&#xff09; 章节内容 上一…

python中的数据类型-适合新手-比较完善(写了好久……)

作者的话 首先&#xff0c;我先申明&#xff0c;以下思路仅为个人理解&#xff0c;如有不同&#xff0c;望指导&#xff0c;谢谢。 数据类型它是什么&#xff0c;有什么用&#xff0c;怎么用就是它的全部内容&#xff0c;知识框架串联起来之后就是这三部分内容&#xff0c;没有…

【网络安全科普】勒索病毒 防护指南

勒索病毒简介 勒索病毒是一种恶意软件&#xff0c;也称为勒索软件&#xff08;Ransomware&#xff09;&#xff0c;其主要目的是在感染计算机后加密用户文件&#xff0c;并要求用户支付赎金以获取解密密钥。这种类型的恶意软件通常通过电子邮件附件、恶意链接、下载的软件或漏洞…

数论基础知识

整除 辗转相除法 同余 模计算机 一次同余方程 费马小定理&#xff5c;欧拉定理&#xff5c;威尔逊定理 孙子定理(中国剩余定理) 快速指数算法&#xff08;快速模乘法&#xff09;&#xff08;反复平方乘&#xff09; 模重复平方法 二次剩余 Legendre符号欧拉判别法 原根 gc…

golang 解压带密码的zip包

目录 Zip文件详解ZIP 文件格式主要特性常用算法Zip格式结构图总览Zip文件结构详解数据区本地文件头文件数据文件描述 中央目录记录区&#xff08;核心目录记录区 &#xff09;中央目录记录尾部区 压缩包解压过程方式1 通过解析中央目录区来解压方式2 通过读取本地文件头来解压两…

JVM常用工具中jmap实现手动进行堆转储(heap dump文件)并使用MAT(Memory Analyzer Tool)进行堆分析-内存消耗分析

场景 JVM-常用工具(jps、jstat、jinfo、jmap、jhat、jstack、jconsole、jvisualvm)使用&#xff1a; JVM-常用工具(jps、jstat、jinfo、jmap、jhat、jstack、jconsole、jvisualvm)使用_jvm分析工具-CSDN博客 上面讲了jmap的简单使用。 下面记录其常用功能&#xff0c;实现堆…

C#+layui+echarts实现动态生成折线图

概要 C#layuiecharts实现动态生成折线图 整体架构流程 后端是c#语言编写的业务流程,前端是layui和echarts 技术细节 1.先看echarts折线图需要什么样子的数据,在想后端怎么处理 2.后端代码 List<ValveTempData> list new List<ValveTempData>(); string …