首页 > 编程语言 >优先队列的基本实现【数据结构与算法—TypeScript 实现】

优先队列的基本实现【数据结构与算法—TypeScript 实现】

时间:2024-04-09 11:48:09浏览次数:24  
标签:TypeScript return 队列 value priorityQueue length heap 数据结构 data

笔记整理自 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,return,队列,value,priorityQueue,length,heap,数据结构,data
From: https://www.cnblogs.com/itchaox/p/18123591

相关文章

  • 插入排序的基本实现【数据结构与算法—TypeScript 实现】
    笔记整理自coderwhy『TypeScript高阶数据结构与算法』课程概念本质:将数列分为已排序和未排序,将未排序中的元素插入到已排序中的合适位置特性复杂度分析时间复杂度:最好情况:O(n),有序序列最坏情况:O(n^2),倒序序列平均情况:O(n^2),随机数列空间复杂度:O(n),原地排序使......
  • 选择排序的基本实现【数据结构与算法—TypeScript 实现】
    笔记整理自coderwhy『TypeScript高阶数据结构与算法』课程概念本质:两两元素相比较,先扫描一遍未排序数列,把未排序的数列中的最小(大)元素,放到数列的已排序的末尾特性选择排序是冒泡排序的优化版本,主要优化了交换的过程在所有完全依靠交换去移动元素的排序方法中,选择排......
  • 2024.4.8 数据结构课件补题
    [AGC055B]ABCSupremacy令ABC分别为1,2,3,然后令\(s_i=(s_i-i)\textmod3\)且结果大于0。然后可以发现三种组合均为连贯的三个相同数。且可以自由移动。可以选择每遇到三个相同数就删掉,或者不断加入栈,如果栈顶三个数相同全部弹出。再比较剩下的数即可。#include<bits......
  • Day5.一刷数据结构算法(C语言版) 242有效的字母异位词; 349两个数组的交集; 202快乐数; 1
        现在我们开始学习哈希表.        经过本次学习我认识到c++的便利,但是我使用的是c,那些功能c又用不了,导致代码长度一下子拉长了...        一刷的时候我还是先用c吧,等二刷的时候试试c++.        进入正题:        什么时候......
  • 深入理解数据结构——栈
    前言:在学习完数据结构顺序表和链表之后,其实我们就可以做很多事情了,后面的栈和队列,其实就是对前面的顺序表和链表的灵活运用,今天我们就来学习一下栈的原理和应用。准备工作:本人习惯将文件放在test.c、SeqList.c、SeqList.h三个文件中来实现,其中test.c用来放主函数,SeqList.c......
  • 【数据结构与算法】:堆排序和选择排序
    1.堆排序堆排序是一种比较复杂的排序算法,因为它的流程比较多,理解起来不会像冒泡排序和选择排序那样直观。1.1堆的结构要理解堆排序,首先要理解堆。堆的逻辑结构是一棵完全二叉树,物理结构是一个数组。(如果不知道什么是二叉树,请前往我的主页查看)。所以堆是一个用数组表......
  • 队列-单端队列
    队列和栈非常类似,栈的一端是封闭的,类似一口深井,遵循先进后出原则FILO.队列则两端是放开的,抽象于现实世界的排队现象,遵循先进先出原则FIFO.队列在尾部进行元素的新增,称为"入队",然后从头部移除元素,成为"出队".生活中我们去坐火车进站检票,去某个机关办理......
  • 突破编程_C++_网络编程(Windows 套接字(常用数据结构))
    1WSADATAWSADATA结构体包含了关于Winsock实现的一些详细信息,定义如下:structWSAData{WORDwVersion;//Winsock版本号WORDwHighVersion;//Winsock动态库支持的最高版本号charszDescription[WSADESCRIPTION_LEN+1];//Winsock描......
  • typescript学习文档(二)
    1、安装typescript全局安装:npminstall-gtypescript检查是否安装成功(出现版本号表示安装成功):tsc-v如果使用tsc指令出现如下错误:解决办法:以管理员的身份运行vscode终端执行:get-ExecutionPolicy,结果:Restricted终端执行:set-ExecutionPolicyRemoteSigned终端执行:get......
  • MySQL 底层数据结构 聚簇索引以及二级索引 Explain的使用
    数据结构我们知道MySQL的存储引擎Innodb默认底层是使用B+树的变种来存储数据的下面我们来复习一下B树存储+B树存储 +哈希存储的区别哈希存储,只能使用等值查询B树与B+树存储我们知道B+树实际上就是B树的变种那么为啥使用B+树而不是使用B树呢?我们知道效率的高低......