UNPKG

s2-tools

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

113 lines 2.96 kB
/** * # Priority Queue * * ## Description * A priority queue is a data structure that stores elements in a specific order. * * ## Usage * * ```ts * import { PriorityQueue } from 's2-tools'; * * const queue = new PriorityQueue<number>(); * * queue.push(1); * queue.push(2); * * const current = queue.peek(); // 1 * console.log(queue.length); // 2 * let next = queue.pop(); // 1 * console.log(queue.length); // 1 * next = queue.pop(); // 2 * console.log(queue.length); // 0 * ``` */ export class PriorityQueue { data; compare; #length = 0; /** * @param data - initial data * @param compare - compare function */ constructor(data = [], compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0)) { this.data = data; this.compare = compare; this.#length = data.length; if (this.#length > 0) { for (let i = (this.#length >> 1) - 1; i >= 0; i--) this.#down(i); } } /** @returns - the number of items */ get length() { return this.#length; } /** * Push an item into the queue * @param item - the item to store */ push(item) { this.data.push(item); this.#up(this.#length++); } /** * Access the top item, remove it, and return it * @returns - the top item */ pop() { if (this.#length === 0) return; const top = this.data.at(0); const bottom = this.data.pop(); if (bottom === undefined) return; if (--this.#length > 0) { this.data[0] = bottom; this.#down(0); } return top; } /** * Peek at the top item without removing it * @returns - the top item */ peek() { return this.data.at(0); } /** * @param pos - the position to reorder */ #up(pos) { const { data, compare } = this; const item = data[pos]; while (pos > 0) { const parent = (pos - 1) >> 1; const current = data[parent]; if (compare(item, current) >= 0) break; data[pos] = current; pos = parent; } data[pos] = item; } /** @param pos - the position to start reordering */ #down(pos) { const { data, compare } = this; const halfLength = this.#length >> 1; const item = data[pos]; while (pos < halfLength) { let bestChild = (pos << 1) + 1; // initially it is the left child const right = bestChild + 1; if (right < this.#length && compare(data[right], data[bestChild]) < 0) { bestChild = right; } if (compare(data[bestChild], item) >= 0) break; data[pos] = data[bestChild]; pos = bestChild; } data[pos] = item; } } //# sourceMappingURL=priorityQueue.js.map