/** * Represents a queue data structure. * @class */ export class Queue { /** * Creates an instance of Queue. * @constructor */ constructor() { /** * The data array to store elements. * @type {Array} * @private */ this.data = []; /** * The index of the front element in the queue. * @type {number} * @private */ this.head = 0; } /** * Retrieves the front element of the queue. * @returns {*} The front element of the queue. */ front() { return this.data[this.head]; } /** * Retrieves the back element of the queue. * @returns {*} The back element of the queue. */ back() { return this.data[this.data.length - 1]; } /** * Removes the back element from the queue. * @throws {QueueEmptyError} Throws an error if the queue is empty. */ popBack() { if (this.data.length == this.head) { throw new QueueEmptyError(); } this.data.length -= 1; } /** * Checks if the queue is empty. * @returns {boolean} True if the queue is empty, otherwise false. */ empty() { return this.data.length == this.head; } /** * Returns the size of the queue. * @returns {number} The size of the queue. */ size() { return this.data.length - this.head; } /** * Alias for the size() method. * @type {number} */ get length() { return this.size(); } /** * Pushes elements into the queue. * @param {...*} elements The elements to push into the queue. */ push() { this.data.push.apply(this.data, arguments); } /** * Removes the front element from the queue. * @throws {QueueEmptyError} Throws an error if the queue is empty. */ popFront() { if (this.empty()) { throw new QueueEmptyError(); } this.head += 1; if (this.head == this.data.length) { this.data = []; this.head = 0; return; } if (this.head >= this.data.length >> 1 && this.head >= 16) { this.data = this.data.slice(this.head); this.head = 0; } } /** * Returns an iterator that allows iterating through the elements of the queue. * @returns {*} elements of the queue. * @generator */ *[Symbol.iterator]() { for (let i = this.head; i < this.data.length; i += 1) { yield this.data[i]; } } } /** * Represents an error thrown when attempting operations on an empty queue. * @class */ export class QueueEmptyError extends Error { /** * Creates an instance of QueueEmptyError. * @constructor */ constructor() { super('Queue is empty'); } }