堆结构(Heap)的基本实现【数据结构与算法—TypeScript 实现】
笔记整理自 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 实现】的更多相关文章
- python数据结构与算法
		
最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...
 - [数据结构]——堆(Heap)、堆排序和TopK
		
堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...
 - 数据结构 之 二叉堆(Heap)
		
注:本节主要讨论最大堆(最小堆同理). 一.堆的概念 堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性. 1.结构性质: 堆是一棵被完全填满的二叉树,有可能的 ...
 - 数据结构——堆(Heap)大根堆、小根堆
		
目录 Heap是一种数据结构具有以下的特点: 1)完全二叉树: 2)heap中存储的值是偏序: Min-heap: 父节点的值小于或等于子节点的值: Max-heap: 父节点的值大于或等于子节点的值 ...
 - js数据结构与算法存储结构
		
数据结构(程序设计=数据结构+算法) 数据结构就是关系,没错,就是数据元素相互之间存在的一种或多种特定关系的集合. 传统上,我们把数据结构分为逻辑结构和物理结构. 逻辑结构:是指数据对象中数据元素之间 ...
 - Java数据结构和算法 - 堆
		
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
 - 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列
		
概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...
 - 使用加强堆结构解决topK问题
		
作者:Grey 原文地址: 使用加强堆结构解决topK问题 题目描述 LintCode 550 · Top K Frequent Words II 思路 由于要统计每个字符串的次数,以及字典序,所以, ...
 - 纸上谈兵:堆(heap)
		
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 堆(heap)又被为优先队列(priority queue).尽管名为优先队列,但 ...
 - 二叉堆(binary heap)
		
堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因 ...
 
随机推荐
- nginx 基本功能
			
1.nginx简介 官方文档 Nginx是一个高性能WEB服务器,除它之外Apache.Tomcat.Jetty.IIS,它们都是Web服务器,或者叫做WWW(World Wide Web)服务器,相 ...
 - Java   抽象类的应用:模板方法的设计模式
			
1 package com.bytezreo.template; 2 3 /** 4 * 5 * @Description 抽象类的应用:模板方法的设计模式 6 * @author Bytezero· ...
 - Java  属性赋值的先后顺序
			
1 package com.bytezero.circle; 2 /** 3 * 4 * @Description 5 * @author Bytezero·zhenglei! Email:42049 ...
 - 2、dubbo原理
			
图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖 ...
 - 为什么现在连Date类都不建议使用了?
			
一.有什么问题吗java.util.Date? java.util.Date(Date从现在开始)是一个糟糕的类型,这解释了为什么它的大部分内容在 Java 1.1 中被弃用(但不幸的是仍在使用). ...
 - mybatis查询大批量数据的几种方式
			
问题背景 公司里有很多需要跑批数据的场景,这些数据几十万到几千万不等,目前我们采用的是分页查询,但是分页查询有个深度分页问题,上百万的数据就会查询的很慢 常规解决方案 全量查询 分页查询 流式查询 游 ...
 - Git进阶命令-revert
			
有关Git,之前有写过两篇文章: Git五个常见问题及解决方法 Git进阶命令-reset 一.revert命令使用场景 有一天项目经理跟你说,你开发上线的代码有问题,需要马上撤回. 撤回?你第一反应 ...
 - Spring Boot学习日记18
			
JDBCTemplate execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句: update方法及batchUpdate方法:update方法用于执行新增.修改.删除等语句:bat ...
 - OpenLayers 点击显示经纬度Demo
			
这里给大家分享我在OpenLayers 地图开发工作中总结出的一下代码和注意点,希望对大家有所帮助 效果如下: 核心代码展示:附带讲解注释 var map = new ol.Map({ // 初始化地 ...
 - 如何打造一个花里胡哨的Github个人主页?
			
1.介绍 2.使用 2.1.创建一个同名仓库 2.2.引用模板 2.3.为内容添加有趣模块 2.3.1.徽章badge 2.3.2.waka 时间展示 2.3.3.展示 GitHub stars 等信 ...