前端算法:堆

news/2024/10/24 12:26:29/

目录

一、堆

1.堆是什么?

2.堆的性质

3.堆的实现

4.基本操作

5.时间复杂度

 二、代码实现

1.最大堆实现

2.最小堆实现


一、堆

1.堆是什么?

堆能用树来表示,并且一般树的实现都是通过链表,而二叉堆是一种特殊的堆,它用完全二叉树来表示,却可以利用数组来实现。

平时使用最多的是二叉堆,它可以用完全二叉树俩表示,二叉堆易于存储,并且便于索引。

注意:堆的数据结构像树,但是通过数组实现、

2.堆的性质

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

3.堆的实现

  1. 通常使用数组实现。对于任意节点在索引 i
    • 父节点的索引为 (i - 1) / 2
    • 右子节点的索引为 2*i + 2
    • 左子节点的索引为 2*i + 1

4.基本操作

  • 插入:将新元素添加到数组末尾,随后进行“上浮”操作,保持堆的性质。
  • 删除(通常是删除根节点):将根节点与最后一个节点交换,移除最后节点,随后进行“下沉”操作,恢复堆的性质。

5.时间复杂度

插入和删除操作的时间复杂度为 O(log n),而查找最大/最小值的时间复杂度为 O(1)。

 二、代码实现

1.最大堆实现

class MaxHeap {constructor() {this.heap = [];}// 插入元素insert(value) {this.heap.push(value);this.bubbleUp();}// 向上调整bubbleUp() {let index = this.heap.length - 1;while (index > 0) {const parentIndex = Math.floor((index - 1) / 2);if (this.heap[index] <= this.heap[parentIndex]) break;[this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];index = parentIndex;}}// 移除最大值extractMax() {if (this.heap.length === 0) return null;if (this.heap.length === 1) return this.heap.pop();const max = this.heap[0];this.heap[0] = this.heap.pop();this.bubbleDown();return max;}// 向下调整bubbleDown() {let index = 0;const length = this.heap.length;while (true) {let leftChildIndex = 2 * index + 1;let rightChildIndex = 2 * index + 2;let largest = index;if (leftChildIndex < length && this.heap[leftChildIndex] > this.heap[largest]) {largest = leftChildIndex;}if (rightChildIndex < length && this.heap[rightChildIndex] > this.heap[largest]) {largest = rightChildIndex;}if (largest === index) break;[this.heap[index], this.heap[largest]] = [this.heap[largest], this.heap[index]];index = largest;}}// 查看最大值peek() {return this.heap[0] || null;}// 获取堆的数组表示getHeap() {return this.heap;}
}// 使用示例
const maxHeap = new MaxHeap();
maxHeap.insert(10);
maxHeap.insert(20);
maxHeap.insert(5);
console.log(maxHeap.getHeap()); // [ 20, 10, 5 ]
console.log(maxHeap.extractMax()); // 20
console.log(maxHeap.getHeap()); // [ 10, 5 ]

2.最小堆实现

class MinHeap {constructor() {this.heap = [];}// 插入元素insert(value) {this.heap.push(value);this.bubbleUp();}// 向上调整bubbleUp() {let index = this.heap.length - 1;while (index > 0) {const parentIndex = Math.floor((index - 1) / 2);if (this.heap[index] >= this.heap[parentIndex]) break;[this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];index = parentIndex;}}// 移除最小值extractMin() {if (this.heap.length === 0) return null;if (this.heap.length === 1) return this.heap.pop();const min = this.heap[0];this.heap[0] = this.heap.pop();this.bubbleDown();return min;}// 向下调整bubbleDown() {let index = 0;const length = this.heap.length;while (true) {let leftChildIndex = 2 * index + 1;let rightChildIndex = 2 * index + 2;let smallest = index;if (leftChildIndex < length && this.heap[leftChildIndex] < this.heap[smallest]) {smallest = leftChildIndex;}if (rightChildIndex < length && this.heap[rightChildIndex] < this.heap[smallest]) {smallest = rightChildIndex;}if (smallest === index) break;[this.heap[index], this.heap[smallest]] = [this.heap[smallest], this.heap[index]];index = smallest;}}// 查看最小值peek() {return this.heap[0] || null;}// 获取堆的数组表示getHeap() {return this.heap;}
}// 使用示例
const minHeap = new MinHeap();
minHeap.insert(10);
minHeap.insert(20);
minHeap.insert(5);
console.log(minHeap.getHeap()); // [ 5, 10, 20 ]
console.log(minHeap.extractMin()); // 5
console.log(minHeap.getHeap()); // [ 10, 20 ]


http://www.ppmy.cn/news/1541595.html

相关文章

Ivanti云服务被攻击事件深度解析:安全策略构建与未来反思

攻击事件背景 近期&#xff0c;威胁情报和研究机构Fortinet FortiGuard Labs发布了一份关于针对IT解决方案提供商Ivanti云服务设备&#xff08;Ivanti Cloud Services Appliance&#xff0c;CSA&#xff09;的复杂网络攻击的详细分析。 该攻击被怀疑是由国家级对手发起&#xf…

2024软考网络工程师笔记 - 第8章.网络安全

文章目录 网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型3️⃣安全目标与技术 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552…

android 利用adb将apk安装到模拟器中的方法

1、安装完成了sdk以后&#xff0c;会有一个工具集&#xff0c;里面有一个adb.exe&#xff0c;这个文件可以查看模拟器列表&#xff0c;及安装apk到模拟器中。 可以将这个目录加到环境变量中&#xff0c;这样就不用定位到目录&#xff0c; 然后使用adb命令了。 2、这里我们先定…

数据结构之链表——单向链表(完结)

单向链表 链表跟数据表有着本质的关系 回顾一下顺序表&#xff1a;顺序表分为动态顺序表和静态顺序表 静态顺序表&#xff1a;静态顺序表详解 动态顺序表&#xff1a;动态顺序表详解 顺序表的本质还是数组&#xff0c;通过数组来存储数据&#xff0c;如果我们需要插入一个数据…

PostgreSQL与MySQL在语法上的区别

PostgreSQL与MySQL在语法上的区别 在数据库管理系统中&#xff0c;PostgreSQL和MySQL都是非常受欢迎的选择。虽然它们都是一种关系型数据库管理系统(RDBMS)&#xff0c;但它们在语法上有一些显著的区别。本文将介绍PostgreSQL和MySQL在语法上的主要区别。 数据类型 PostgreS…

WPF中的Style如何使用

在 WPF 中&#xff0c;Style 是一个非常重要的概念&#xff0c;它用于定义控件的默认外观和行为。以下是如何使用 Style 的一些基本步骤和示例&#xff1a; 1. 定义 Style 资源 通常在 XAML 的资源部分&#xff08;ResourceDictionary&#xff09;中定义样式。 2. 指定 Targ…

大模型预训练“狼人杀”,是谁悄悄掉队了?

国内最顶尖的这些大模型初创公司&#xff0c;现在站到了该做取舍的十字路口。 十月初&#xff0c;市场中传出消息&#xff0c;称智谱AI、零一万物、MiniMax、百川智能、月之暗面、阶跃星辰这六家被称为“AI六小虎”的中国大模型独角兽中&#xff0c;有两家公司已经决定逐步放弃…

AAPL: Adding Attributes to Prompt Learning for Vision-Language Models

文章汇总 当前的问题 1.元标记未能捕获分类的关键语义特征 如下图(a)所示&#xff0c; π \pi π在类聚类方面没有显示出很大的差异&#xff0c;这表明元标记 π \pi π未能捕获分类的关键语义特征。我们进行简单的数据增强后&#xff0c;如图(b)所示&#xff0c;效果也是如…