diff --git a/JavaScript/1-queue.js b/JavaScript/1-queue.js index 0ed7a29..4a25594 100644 --- a/JavaScript/1-queue.js +++ b/JavaScript/1-queue.js @@ -1,19 +1,62 @@ 'use strict'; + +const _items = Symbol('items'); +const _size = Symbol('size'); + class Queue { - #buffer = []; + constructor() { - get length() { - return this.#buffer.length; + this[(_items)] = []; + this[(_size)] = 0; } + enqueue(item) { - this.#buffer.push(item); + + this[(_items)].push(item); + this[(_size)]++; } + dequeue() { - return this.#buffer.shift(); + if (this[(_size)] === 0) { + return undefined; + } + this[(_size)]--; + return this[(_items)].shift(); + } + + peek() { + if (this[(_size)] === 0) { + return undefined; + } + return this[(_items)][0]; + } + + isEmpty() { + return this[(_size)] === 0; + } + + length() { + return this[(_size)]; + } + + clear() { + this[(_items)] = []; + this[(_size)] = 0; + } + + *[Symbol.iterator]() { + + for (const item of this[_items]) { + yield item; + } + } + + toArray() { + return [...this[(_items)]]; } } -module.exports = Queue; +module.exports = Queue; \ No newline at end of file diff --git a/TypeScript/queue.js b/TypeScript/queue.js index 7820857..e7ea19a 100644 --- a/TypeScript/queue.js +++ b/TypeScript/queue.js @@ -1,48 +1,88 @@ 'use strict'; class QueueNode { + #buffer; + #size; + #readIndex; + #writeIndex; + #length; + #next; + constructor({ size }) { - this.length = 0; - this.size = size; - this.readIndex = 0; - this.writeIndex = 0; - this.buffer = new Array(size); - this.next = null; + if (typeof size !== 'number' || size <= 0) { + throw new Error('QueueNode: `size` must be a positive number.'); + } + this.#size = size; + this.#buffer = new Array(size); + this.#readIndex = 0; + this.#writeIndex = 0; + this.#length = 0; + this.#next = null; + } + + get length() { + return this.#length; + } + + get size() { + return this.#size; + } + + get next() { + return this.#next; + } + + set next(node) { + this.#next = node; } enqueue(item) { - if (this.writeIndex >= this.size) return false; - this.buffer[this.writeIndex++] = item; - this.length++; + if (this.#writeIndex >= this.#size) { + return false; + } + this.#buffer[this.#writeIndex++] = item; + this.#length++; return true; } dequeue() { - if (this.length === 0) return null; - const index = this.readIndex++; - const item = this.buffer[index]; - this.buffer[index] = null; - this.length--; - if (this.length === 0) { - this.readIndex = 0; - this.writeIndex = 0; + if (this.#length === 0) { + return null; + } + const item = this.#buffer[this.#readIndex]; + this.#buffer[this.#readIndex] = null; + this.#readIndex++; + this.#length--; + + if (this.#length === 0) { + this.#readIndex = 0; + this.#writeIndex = 0; } return item; } + + peek() { + if (this.#length === 0) return null; + return this.#buffer[this.#readIndex]; + } } class UnrolledQueue { #length = 0; - #nodeSize = 2048; - #head = null; - #tail = null; + #nodeSize; + #head; + #tail; constructor(options = {}) { - const { nodeSize } = options; - if (nodeSize) this.#nodeSize = nodeSize; - const node = new QueueNode({ size: this.#nodeSize }); - this.#head = node; - this.#tail = node; + this.#nodeSize = options.nodeSize || 2048; + + if (typeof this.#nodeSize !== 'number' || this.#nodeSize <= 0) { + throw new Error('UnrolledQueue: `nodeSize` must be a positive number.'); + } + + const initialNode = new QueueNode({ size: this.#nodeSize }); + this.#head = initialNode; + this.#tail = initialNode; } get length() { @@ -51,23 +91,56 @@ class UnrolledQueue { enqueue(item) { if (!this.#head.enqueue(item)) { - const node = new QueueNode({ size: this.#nodeSize }); - this.#head.next = node; - this.#head = node; + const newNode = new QueueNode({ size: this.#nodeSize }); + this.#head.next = newNode; + this.#head = newNode; this.#head.enqueue(item); } this.#length++; } dequeue() { - if (this.#length === 0) return null; + if (this.#length === 0) { + return null; + } + const item = this.#tail.dequeue(); this.#length--; - if (this.#tail.length === 0 && this.#tail.next) { + + if (this.#tail.length === 0 && this.#tail.next !== null) { this.#tail = this.#tail.next; } + return item; } + + isEmpty() { + return this.#length === 0; + } + + peek() { + if (this.#length === 0) { + return null; + } + return this.#tail.peek(); + } + + clear() { + const initialNode = new QueueNode({ size: this.#nodeSize }); + this.#head = initialNode; + this.#tail = initialNode; + this.#length = 0; + } + + *[Symbol.iterator]() { + let currentNode = this.#tail; + while (currentNode) { + for (let i = currentNode.readIndex; i < currentNode.writeIndex; i++) { + yield currentNode.buffer[i]; + } + currentNode = currentNode.next; + } + } } -module.exports = { UnrolledQueue }; +module.exports = { UnrolledQueue }; \ No newline at end of file