优先队列的基本实现【数据结构与算法—TypeScript 实现】
笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程
特性
- 效率比普通队列高
- 每个出队元素拥有最高优先级
- 可以用 数组、链表 等数据结构实现,但是 堆结构 是最常用的实现方式
设计
实现方式:基于 堆结构 实现,堆结构底层基于数组实现
属性:
- heap:存放队列元素
方法:
- enqueue:入队
- dequeue:出队
- peek:查看队首元素
- isEmpty:判断队列是否为空
- size:获取队列长度
具体代码
堆结构实现:
export default 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]);
const heap = new Heap<number>();
heap.insert(1);
heap.insert(4);
heap.insert(15);
console.log(heap.extract());
console.log(heap.extract());
console.log(heap);
基于堆结构实现优先队列:
// 基于上面的堆结构
import Heap from './heap.ts';
class PriorityNode<T> {
value: T;
priority: number;
constructor(value: T, priority: number) {
this.value = value;
this.priority = priority;
}
valueOf() {
return this.priority;
}
}
class PriorityQueue<T> {
private heap: Heap<PriorityNode<T>> = new Heap();
enqueue(value: T, priority: number) {
const newNode = new PriorityNode<T>(value, priority);
this.heap.insert(newNode);
}
dequeue(): T | undefined {
return this.heap.extract()?.value;
}
peek(): T | undefined {
return this.heap.peek()?.value;
}
isEmpty() {
return this.heap.isEmpty();
}
get size() {
return this.heap.size;
}
}
const priorityQueue = new PriorityQueue<string>();
priorityQueue.enqueue('itchao', 124);
priorityQueue.enqueue('why', 34);
priorityQueue.enqueue('james', 38);
console.log(priorityQueue.dequeue());
console.log(priorityQueue.dequeue());
console.log(priorityQueue.dequeue());
优先队列的基本实现【数据结构与算法—TypeScript 实现】的更多相关文章
- 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述
定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...
- 数据结构和算法(Golang实现)(24)排序算法-优先队列及堆排序
优先队列及堆排序 堆排序(Heap Sort)由威尔士-加拿大计算机科学家J. W. J. Williams在1964年发明,它利用了二叉堆(A binary heap)的性质实现了排序,并证明了二叉 ...
- 用python语言讲解数据结构与算法
写在前面的话:关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem ...
- 数据结构和算法 – 3.堆栈和队列
1.栈的实现 后进先出 自己实现栈的代码 using System; using System.Collections.Generic; using System.Linq; using ...
- [0x00 用Python讲解数据结构与算法] 概览
自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...
- 《数据结构与算法JavaScript描述》
<数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...
- 【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现
本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型 ...
- JavaScript 版数据结构与算法(二)队列
今天,我们要讲的是数据结构与算法中的队列. 队列简介 队列是什么?队列是一种先进先出(FIFO)的数据结构.队列有什么用呢?队列通常用来描述算法或生活中的一些先进先出的场景,比如: 在图的广度优先遍历 ...
- Java数据结构和算法 - 栈和队列
Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...
- 常用数据结构及算法C#/Java实现
常用数据结构及算法C#实现 1.冒泡排序.选择排序.插入排序(三种简单非递归排序) ,, , , , , , , , , }; //冒泡排序 int length = waitSort.Length; ...
随机推荐
- 【Azure 存储服务】MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以正常播放却无法拖拽视频的进度
问题描述 把MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以正常播放却无法拖拽视频的进度,这是什么情况呢? 问题解答 因为MP4上传到Azure Blob后,根据公开的 ...
- redisson分布式锁lua脚本翻译
1.获取锁 lock入参:keys[1]:自定义锁的key RLock lock = redissonClient.getLock(lockKey);argv[1]=锁的租期,默认30s argv ...
- 案例8:将"picK"的大小写互换
最终输出结果为PICk. 需要先计算两个字母之间的间隔,比如a和A之间的间隔为多少. 然后在将大写字母转换为小写字母,加上间隔的值: 将小写字母转换为大写字母,减去间隔的值. 示例代码如下: #def ...
- win10 有 休眠 功能,将内存保存到文件,开机10秒左右,恢复之前idea等所有软件
休眠 休眠 休眠 重要的事情说三遍. 提示,默认不显示,需要控制面板 电源里面设置下.
- 关于云XR介绍,以及5G时代云化XR的发展机遇
XR技术进入全面沉浸化时代 基于云化XR技术将大幅降低XR终端设备的计算负荷和能耗,摆脱线缆的束缚,XR终端设备将变得更轻.更沉浸.更智能.更有利于商业化. 网络XR终端能力的提升,将推动XR技术进入 ...
- 记录--整会promise这8个高级用法
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 发现很多人还只会promise常规用法 在js项目中,promise的使用应该是必不可少的,但我发现在同事和面试者中,很多中级或以上的前端 ...
- TP6框架--EasyAdmin学习笔记:Excel表单导入数据库
这是我写的学习EasyAdmin的第四章,这一章我给大家分享下Excel表单导入数据库的全流程需要怎么处理并提供案例 首先给大家看下这个功能的原理,下面是PHP连接打印机的代码 public func ...
- 记录--uniapp上如何实现安卓app微信登录功能(操作流程总结)
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 uniapp上如何实现安卓app微信登录功能?下面本篇文章给大家分享一下uniapp上实现安卓app微信登录的权限申请.开发的具体操作流程 ...
- 性能测试系列:Jmeter使用记录
jmeter配置环境变量vi /etc/profileexport PATH=$PATH:/tmp/jmeter/apache-jmeter-5.4.1/binsource /etc/profile ...
- 快速上手系列:CSS
一 选择符 1 通配:*{} 所有元素 类:p{} 如 p 标签等相应元素 ID:#id{} 使用相应 id 属性的元素样式 类:.类名{} 使用相应 class 属性的元素样式 包含:div p{} ...