[js][utility]add Queue

This commit is contained in:
方而静 2024-02-10 21:10:48 +08:00
parent c350abc5f6
commit 18e8b4f44f
Signed by: szTom
GPG Key ID: 072D999D60C6473C
2 changed files with 128 additions and 0 deletions

View File

@ -1 +1,2 @@
export { areArrayBuffersEqual } from './buffer.mjs';
export { Queue, QueueEmptyError } from './queue.mjs';

127
shared/utility/queue.mjs Normal file
View File

@ -0,0 +1,127 @@
/**
* 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');
}
}