@figliolia/data-structures
Version:
Efficient data structures for every day programming
100 lines (99 loc) • 2.37 kB
JavaScript
/**
* Priority Queue
*
* A bucket queue that sorts elements based on the priority level specified
*
* ```typescript
* import { PriorityQueue } from "@figliolia/data-structures";
*
* const queue = new PriorityQueue<number>();
* queue.push(1, 3);
* queue.push(2, 2);
* queue.push(3, 1);
* queue.length // 3
* // queue = [[3], [2], [1]]
* while(!queue.isEmpty) {
* queue.pop() // 3, 2, 1
* }
* ```
*/
export class PriorityQueue {
buckets = [];
maxPriority;
priorities = {};
constructor(max = Infinity) {
this.maxPriority = max;
}
/**
* Push
*
* Adds a new element to the queue at the specified priority level
*/
push(priority, value) {
if (priority > this.maxPriority) {
throw new RangeError("Max Priority exceeded");
}
const bucket = this.buckets[priority] || [];
bucket.push(value);
this.buckets[priority] = bucket;
this.priorities[priority] = true;
}
/**
* Pop
*
* Removes the last element added to the highest available priority
*/
pop() {
for (const [p, bucket] of this) {
const item = bucket.pop();
if (!bucket.length) {
delete this.priorities[p];
}
return item;
}
}
/**
* Poll
*
* Returns a reference to the last element added to the highest available priority
*/
poll() {
for (const [_, bucket] of this) {
return bucket[bucket.length - 1];
}
}
/**
* Length
*
* Returns the total number of items in the queue
*/
get length() {
let length = 0;
for (const [_, bucket] of this) {
length += bucket.length;
}
return length;
}
/**
* Is Empty
*
* Returns true if the queue contains no items
*/
get isEmpty() {
for (const _ of this) {
return false;
}
return true;
}
*[Symbol.iterator]() {
const keys = Object.keys(this.priorities);
const { length } = keys;
for (let i = 0; i < length; i++) {
const key = parseInt(keys[i]);
const bucket = this.buckets[key];
if (bucket && bucket.length) {
yield [key, bucket];
}
}
}
}