笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程

概念

本质:一种特殊的树结构,由 完全二叉树 实现

  • 多数情况为二叉堆
  • 二叉堆:最大堆、最小堆
    • 最大堆:堆上的每个节点都的 大于等于(>=) 其子节点
    • 最小堆:堆上的每个节点都 小于等于(<=) 其子节点

特性

  • 高效解决获取最大值和最小值问题(Top K 问题)
  • 底层使用 数组 实现

索引问题:

  • i = 0 为根节点
  • 父节点索引:Math.floor((i - 1) / 2)
  • 左子节点索引:2i + 1
  • 右子节点索引:2i + 2
  • 最后一个非叶子节点索引:Math.floor((this.length - 1) / 2)

设计

属性:

  • data:存储堆中的元素,通常使用数组实现
  • length:堆中元素的数量

方法:

  • insert(value):插入元素
  • extract:提取 最大值 / 最小值
  • peek:返回 最大值 / 最小值
  • size:获取堆数量
  • isEmpty:判断是否为空
  • buildHeap(list):通过列表构造堆
  • swap(i, j):两数交换

具体实现代码


class Heap<T> {
// 存储堆元素
private data: T[] = []; // 堆元素数量
private length: number = 0; constructor(list: T[] = []) {
this.buildHeap(list);
} // 两数交换
private swap(i: number, j: number) {
const temp = this.data[i];
this.data[i] = this.data[j];
this.data[j] = temp;
} // 获取堆数量
get size(): number {
return this.length;
} // 返回最大值/最小值
peek(): T | undefined {
return this.data[0];
} // 判断是否为空
isEmpty(): boolean {
return this.length === 0;
} // 插入元素
insert(value: T) {
// 直接把新元素放入数组尾部
this.data.push(value);
this.length++; this.heapify_up();
} // 上滤操作
heapify_up() {
// 获取插入元素索引
let currentIndex = this.length - 1; // 只要 currentIndex > 0 就一直循环
while (currentIndex > 0) {
// 获取父节点索引
let parentIndex = Math.floor((currentIndex - 1) / 2); // 子节点小于父子点,不需交换数据
if (this.data[currentIndex] <= this.data[parentIndex]) {
break;
} // 交换父子节点数据
this.swap(currentIndex, parentIndex); // 更新当前节点索引
currentIndex = parentIndex;
}
} // 提取
extract(): T | undefined {
// 1. 边界情况处理
if (this.length === 0) return undefined;
if (this.length === 1) {
this.length--;
return this.data.pop();
} // 2. 提取并需要返回的最大值
const topValue = this.data[0];
this.data[0] = this.data.pop()!;
this.length--; // 3. 维护最大堆的特性:下滤操作
this.heapify_down(0); return topValue;
} // 下滤操作
heapify_down(start: number) {
let index = start; while (2 * index + 1 < this.length) {
let leftChildIndex = 2 * index + 1;
let rightChildIndex = 2 * index + 2;
let largerIndex = leftChildIndex; if (rightChildIndex < this.length && this.data[rightChildIndex] > this.data[leftChildIndex]) {
largerIndex = rightChildIndex;
} // 子节点大于当前节点,则交换位置
if (this.data[largerIndex] > this.data[index]) {
this.swap(largerIndex, index);
index = largerIndex;
} else {
break;
}
}
} // 原地建堆
buildHeap(list: T[]) {
this.data = list;
this.length = list.length; // 获取最后一个非叶子节点的索引
const start = Math.floor((this.length - 1) / 2); for (let i = start; i >= 0; i--) {
this.heapify_down(i);
}
}
} const heap = new Heap<number>([9, 11, 20, 56, 23, 45]); // heap.insert(1);
// heap.insert(4);
// heap.insert(15); // console.log(heap.extract()); console.log(heap);

堆结构(Heap)的基本实现【数据结构与算法—TypeScript 实现】的更多相关文章

  1. python数据结构与算法

    最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...

  2. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  3. 数据结构 之 二叉堆(Heap)

    注:本节主要讨论最大堆(最小堆同理). 一.堆的概念     堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性.     1.结构性质:     堆是一棵被完全填满的二叉树,有可能的 ...

  4. 数据结构——堆(Heap)大根堆、小根堆

    目录 Heap是一种数据结构具有以下的特点: 1)完全二叉树: 2)heap中存储的值是偏序: Min-heap: 父节点的值小于或等于子节点的值: Max-heap: 父节点的值大于或等于子节点的值 ...

  5. js数据结构与算法存储结构

    数据结构(程序设计=数据结构+算法) 数据结构就是关系,没错,就是数据元素相互之间存在的一种或多种特定关系的集合. 传统上,我们把数据结构分为逻辑结构和物理结构. 逻辑结构:是指数据对象中数据元素之间 ...

  6. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  7. 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列

    概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...

  8. 使用加强堆结构解决topK问题

    作者:Grey 原文地址: 使用加强堆结构解决topK问题 题目描述 LintCode 550 · Top K Frequent Words II 思路 由于要统计每个字符串的次数,以及字典序,所以, ...

  9. 纸上谈兵:堆(heap)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 堆(heap)又被为优先队列(priority queue).尽管名为优先队列,但 ...

  10. 二叉堆(binary heap)

    堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因 ...

随机推荐

  1. 答应我,在vue中不要滥用watch好吗?

    前言 上周五晚上8点,开开心心的等着产品验收完毕后就可以顺利上线.结果产品突然找到我说要加需求,并且维护这一块业务的同事已经下班走了,所以只有我来做.虽然内心一万头草泥马在狂奔,但是嘴里还是一口答应没 ...

  2. MongoDB下载和可视化工具NoSQL Manager for MongoDB 软件的下载,连接数据库

    在官网下载MongoDB的版本为4.0.28,之前试了好几个高版本和低版本,都不行,最后,4.0.28版本好了.下载网页:https://www.mongodb.com/try/download/co ...

  3. 鸿蒙 Harmony 的跨端技术方案

    这两年要说技术上最火的关键字,我想肯定离不开"鸿蒙"两个字. 不管是技术社区还是身边的开发者多多少少都在关注鸿蒙的发展趋势,特别是 HarmonyOS NEXT 版本将进入独立生态 ...

  4. nginx应用及性能调优

    1. Nginx 反向代理实现 说反向代理之前 先说什么是正向代理, 正向代理是指客户端通过 代理服务器访问目标服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 . 例 ...

  5. C1. Good Subarrays (Easy Version)

    思路:我们枚举每一个左端点,对于每一个左端点,寻找最长的满足条件的区间,这个区间长度就是左端点对答案的贡献,可以发现具有单调性,右端点只会前进不会倒退.所以我们两个指针各扫一遍区间就可以. #incl ...

  6. npm install --legacy-peer-deps 安装出现依赖包冲突的解决方案

    npm install --legacy-peer-deps 安装出现依赖包冲突的解决方案 为什么 在安装依赖包的时候,会有依赖包的冲突 比如A包引用了C的1.0版本 B包依赖了C的1.1版本 win ...

  7. 英语字母z解析.drawio

    英语字母z解析.drawio

  8. iMindMap 10 的使用体验 + 讯飞输入法 + windows防火墙 (完美)

    这个软件 最终的效果非常好. 但是有一个硬bug,就是输入光标 搜狗输入法和百度输入法,输入法获取不到,导致输入中文的时候,文字候选框位置特别远. 如果是纯英文 输入使用,就没有这个bug. 总结: ...

  9. 关闭 nginx | taskkill /f /t /im nginx.exe

    stop.bat taskkill /f /t /im nginx.exe pause

  10. C#泛型的类型参数约束

    常用约束 约束告知编译器类型参数必须具备的功能. 在没有任何约束的情况下,类型参数可以是任何类型. 编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类. 如果客户端 ...