From e05b4432d86a97fff67928c596fd442737bf6dd0 Mon Sep 17 00:00:00 2001 From: Fahim Faisaal <57553028+fahimfaisaal@users.noreply.github.com> Date: Fri, 6 May 2022 22:20:55 +0600 Subject: [PATCH] merge: Improved the complexity of dequeue O(n) to O(1) (#1005) * feat: improved memoize function used Map instead of object & used the JSON.stringfy method for generate a valid string as a key * docs: modified documentation * style: format with standard * docs: modified stringify doc * refactor: remove two repetition implementation * feat: added validation, test codes * chore: remove useless words * feat: added types for jest * chore: added link box * feat: added new validation test casses & methods * style: formated with standard * feat: added parse method & test cases * docs: added js docs * chore: added default import export * feat: imporved algorithm via replace method * test: added two test cases * feat: added jest type for suggestions * feat: added `reduceRight` & `trim` method * chore: added helper variable * feat: added new rotation option * Revert "chore: added helper variable" This reverts commit 489544da0a3d479910fbea020d3be3d0d10681bf. * remove: yarn lock * chore: fix grammer * feat: used replace method & added test case * feat: remove revert * chore: added new line * feat: updated the Queue array to linkedlist DS * chore: fixed grammer * resolve: removed capacity related codes, & updated test cases * feat: added length dicrease code on dequeue --- Data-Structures/Queue/Queue.js | 118 +++++++++++++++++------ Data-Structures/Queue/test/Queue.test.js | 60 ++++++------ 2 files changed, 117 insertions(+), 61 deletions(-) diff --git a/Data-Structures/Queue/Queue.js b/Data-Structures/Queue/Queue.js index aa514e977..af7aa884a 100644 --- a/Data-Structures/Queue/Queue.js +++ b/Data-Structures/Queue/Queue.js @@ -1,56 +1,114 @@ /* Queue * A Queue is a data structure that allows you to add an element to the end of -* a list and remove the item at the front. A queue follows a "First In First Out" -* system, where the first item to enter the queue is the first to be removed. This -* implementation uses an array to store the queue. +* a list and remove the item at the front. A queue follows a FIFO (First In First Out) +* system, where the first item to enter the queue is the first to be removed, +* All these operation complexities are O(1). +* This implementation following the linked list structure. */ -// Functions: enqueue, dequeue, peek, view, length, empty class Queue { - // constructor + #size + constructor () { - // This is the array representation of the queue - this.queue = [] + this.head = null + this.tail = null + this.#size = 0 + + return Object.seal(this) } - // methods - // Add a value to the end of the queue - enqueue (item) { - this.queue.push(item) + get length () { + return this.#size } - // Removes the value at the front of the queue + /** + * @description - Add a value to the end of the queue + * @param {*} data + * @returns {number} - The current size of queue + */ + enqueue (data) { + const node = { data, next: null } + + if (!this.head && !this.tail) { + this.head = node + this.tail = node + } else { + this.tail.next = node + this.tail = node + } + + return ++this.#size + } + + /** + * @description - Removes the value at the front of the queue + * @returns {*} - The first data of the queue + */ dequeue () { - if (this.empty()) { + if (this.isEmpty()) { throw new Error('Queue is Empty') } - return this.queue.shift() // remove the item at position 0 from the array and return it + const firstData = this.peekFirst() + + this.head = this.head.next + + if (!this.head) { + this.tail = null + } + + this.#size-- + + return firstData } - // Return the length of the queue - length () { - return this.queue.length - } - - // Return the item at the front of the queue - peek () { - if (this.empty()) { + /** + * @description - Return the item at the front of the queue + * @returns {*} + */ + peekFirst () { + if (this.isEmpty()) { throw new Error('Queue is Empty') } - return this.queue[0] + return this.head.data } - // List all the items in the queue - view (output = value => console.log(value)) { - output(this.queue) + /** + * @description - Return the item at the tail of the queue + * @returns {*} + */ + peekLast () { + if (this.isEmpty()) { + throw new Error('Queue is Empty') + } + + return this.tail.data } - // Return Is queue empty ? - empty () { - return this.queue.length === 0 + /** + * @description - Return the array of Queue + * @returns {Array<*>} + */ + toArray () { + const array = [] + let node = this.head + + while (node) { + array.push(node.data) + node = node.next + } + + return array + } + + /** + * @description - Return is queue empty or not + * @returns {boolean} + */ + isEmpty () { + return this.length === 0 } } -export { Queue } +export default Queue diff --git a/Data-Structures/Queue/test/Queue.test.js b/Data-Structures/Queue/test/Queue.test.js index 734ac74aa..2a8b44ee7 100644 --- a/Data-Structures/Queue/test/Queue.test.js +++ b/Data-Structures/Queue/test/Queue.test.js @@ -1,48 +1,46 @@ -import { Queue } from '../Queue' +import Queue from '../Queue' -describe('Queue', () => { - it('Check enqueue/dequeue', () => { - const queue = new Queue() - queue.enqueue(1) - queue.enqueue(2) - queue.enqueue(8) - queue.enqueue(9) +describe('Testing the Queue DS', () => { + const queue = new Queue() + it('Testing enqueue method', () => { + expect(queue.enqueue(1)).toBe(1) + expect(queue.enqueue(2)).toBe(2) + expect(queue.enqueue(8)).toBe(3) + expect(queue.enqueue(9)).toBe(4) + }) + + it('Testing length after enqueue', () => { + expect(queue.length).toBe(4) + }) + + it('Testing peekFirst & peekLast methods', () => { + expect(queue.peekFirst()).toBe(1) + expect(queue.peekLast()).toBe(9) + }) + + it('Testing toArray method', () => { + expect(queue.toArray()).toEqual([1, 2, 8, 9]) + }) + + it('Testing dequeue method', () => { expect(queue.dequeue()).toBe(1) expect(queue.dequeue()).toBe(2) }) - it('Check length', () => { - const queue = new Queue() - - queue.enqueue(1) - queue.enqueue(2) - queue.enqueue(8) - queue.enqueue(9) - - expect(queue.length()).toBe(4) + it('Testing length after dequeue', () => { + expect(queue.length).toBe(2) }) - it('Check peek', () => { + it('Testing isEmpty method', () => { const queue = new Queue() + expect(queue.isEmpty()).toBeTruthy() queue.enqueue(1) queue.enqueue(2) queue.enqueue(8) queue.enqueue(9) - expect(queue.peek()).toBe(1) - }) - - it('Check empty', () => { - const queue = new Queue() - expect(queue.empty()).toBeTruthy() - - queue.enqueue(1) - queue.enqueue(2) - queue.enqueue(8) - queue.enqueue(9) - - expect(queue.empty()).toBeFalsy() + expect(queue.isEmpty()).toBeFalsy() }) })