Skip to main content

Command Palette

Search for a command to run...

πŸš€ Queue in JavaScript β€” Complete Guide with Code & Practice Problems

πŸš€ Queue in JavaScript

Published
β€’5 min readβ€’View as Markdown
πŸš€ Queue in JavaScript β€” Complete Guide with Code & Practice Problems

A Queue is a linear data structure that follows FIFO (First In, First Out) order.
That means the element inserted first gets removed firstβ€”just like a real-life queue.

In JavaScript, queues can be implemented using:

  • Arrays

  • Linked Lists

  • Stacks

  • Circular Linked Lists

This guide covers all, plus practice questions with full solutions.


πŸ“Œ What is a Queue?

A Queue supports the following operations:

OperationDescription
enqueue(x)Insert an element at the end
dequeue()Remove an element from the front
front()Get front element
back()Get last element
isEmpty()Check if queue is empty
size()Get number of elements

🟦 1. Queue Implementation Using Array

class Queue{
    constructor(){
        this.queue = []
    }

    enqueue(data){
        this.queue.push(data)
    }

    dequeue(){
        return this.isEmpty() ? null : this.queue.shift()
    }

    front(){
        return this.isEmpty() ? null : this.queue.at(0)
    }

    back(){
        return this.isEmpty() ? null : this.queue.at(-1)
    }

    isEmpty(){
        return this.queue.length === 0;
    }

    size(){
        return this.queue.length
    }
}

πŸŸͺ 2. Queue Implementation Using Linked List

class Node{
    constructor(data){
        this.data = data;
        this.next = null;
    }
}

class QueueLinkedList{
    constructor(){
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    enqueue(data){
        const newNode = new Node(data);

        if(this.head === null){
            this.head = newNode;
        } else{
            this.tail.next = newNode;
        }

        this.tail = newNode;
        this.size++;
    }

    dequeue(){
        if(this.isEmpty()){
            return null;
        }

        const deletedItem = this.head.data;
        this.head = this.head.next;
        this.size--;
        return deletedItem;
    }
}

πŸŸ₯ 3. Implement Queue Using Stacks

class QueueStack{
    constructor(){
        this.stack1 = []
        this.stack2 = []
    }

    push(x){
        while(this.stack1.length > 0){
            this.stack2.push(this.stack1.pop())
        }

        this.stack1.push(x);

        while(this.stack2.length > 0){
            this.stack1.push(this.stack2.pop())
        }
    }

    pop(){
        return this.empty() ? null : this.stack1.pop()
    }

    peek(){
        return this.empty() ? null : this.stack1.at(-1)
    }

    empty(){
        return this.stack1.length === 0
    }
}

🟩 4. Circular Queue Using Linked List

class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

class MyCircularQueue {
    constructor(k) {
        this.capacity = k;
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    enQueue(data) {
        if(this.isFull()) return false;

        const newNode = new Node(data);

        if(this.head === null){
            this.head = newNode;
        } else{
            this.tail.next = newNode;
        }

        this.tail = newNode;
        this.tail.next = this.head;
        this.size++;
        return true;
    }

    deQueue() {
        if(this.isEmpty()) return false;

        if(this.head === this.tail){
            this.head = null;
            this.tail = null;
        } else{
            this.head = this.head.next;
            this.tail.next = this.head;
        }

        this.size--;
        return true;
    }

    Front() {
        return this.isEmpty() ? -1 : this.head.data;
    }

    Rear() {
        return this.isEmpty() ? -1 : this.tail.data;
    }

    isEmpty() {
        return this.size === 0;
    }

    isFull() {
        return this.size === this.capacity;
    }
}

🧠 Practice Questions (Solved)


βœ… 1. Implement Queue using Stacks (LeetCode Style)

Already implemented above, but here's the short version:

class MyQueue {
    constructor() {
        this.s1 = [];
        this.s2 = [];
    }

    push(x) {
        this.s1.push(x);
    }

    pop() {
        if(this.empty()) return null;

        while(this.s1.length > 1){
            this.s2.push(this.s1.pop());
        }

        const removed = this.s1.pop();

        while(this.s2.length > 0){
            this.s1.push(this.s2.pop());
        }

        return removed;
    }

    peek() {
        if(this.empty()) return null;

        while(this.s1.length > 1){
            this.s2.push(this.s1.pop());
        }

        const front = this.s1.at(-1);

        while(this.s2.length > 0){
            this.s1.push(this.s2.pop());
        }

        return front;
    }

    empty() {
        return this.s1.length === 0;
    }
}

βœ… 2. Implement Stack using Queue

class MyStack {
    constructor() {
        this.q = [];
    }

    push(x) {
        this.q.push(x);
        for(let i = 0; i < this.q.length - 1; i++){
            this.q.push(this.q.shift());
        }
    }

    pop() {
        return this.q.shift();
    }

    top() {
        return this.q[0];
    }

    empty() {
        return this.q.length === 0;
    }
}

βœ… 3. Design Circular Queue (Array-Based)

class MyCircularQueue {
    constructor(k) {
        this.queue = new Array(k);
        this.head = -1;
        this.tail = -1;
        this.size = k;
    }

    enQueue(value) {
        if (this.isFull()) return false;

        if (this.isEmpty()) this.head = 0;

        this.tail = (this.tail + 1) % this.size;
        this.queue[this.tail] = value;
        return true;
    }

    deQueue() {
        if (this.isEmpty()) return false;

        if (this.head === this.tail) {
            this.head = this.tail = -1;
        } else {
            this.head = (this.head + 1) % this.size;
        }
        return true;
    }

    Front() {
        return this.isEmpty() ? -1 : this.queue[this.head];
    }

    Rear() {
        return this.isEmpty() ? -1 : this.queue[this.tail];
    }

    isEmpty() {
        return this.head === -1;
    }

    isFull() {
        return (this.tail + 1) % this.size === this.head;
    }
}

βœ… 4. Number of Recent Calls (Ping Counter)

(LeetCode: 933)

class RecentCounter {
    constructor() {
        this.queue = [];
    }

    ping(t) {
        this.queue.push(t);

        while (this.queue[0] < t - 3000) {
            this.queue.shift();
        }

        return this.queue.length;
    }
}

βœ… 5. Design Circular Deque

class MyCircularDeque {
    constructor(k) {
        this.arr = new Array(k);
        this.size = k;
        this.front = -1;
        this.rear = -1;
    }

    insertFront(value) {
        if(this.isFull()) return false;

        if(this.isEmpty()) {
            this.front = this.rear = 0;
        } else {
            this.front = (this.front - 1 + this.size) % this.size;
        }
        this.arr[this.front] = value;
        return true;
    }

    insertLast(value) {
        if(this.isFull()) return false;

        if(this.isEmpty()) {
            this.front = this.rear = 0;
        } else {
            this.rear = (this.rear + 1) % this.size;
        }
        this.arr[this.rear] = value;
        return true;
    }

    deleteFront() {
        if(this.isEmpty()) return false;

        if(this.front === this.rear) {
            this.front = this.rear = -1;
        } else {
            this.front = (this.front + 1) % this.size;
        }
        return true;
    }

    deleteLast() {
        if(this.isEmpty()) return false;

        if(this.front === this.rear) {
            this.front = this.rear = -1;
        } else {
            this.rear = (this.rear - 1 + this.size) % this.size;
        }
        return true;
    }

    getFront() {
        return this.isEmpty() ? -1 : this.arr[this.front];
    }

    getRear() {
        return this.isEmpty() ? -1 : this.arr[this.rear];
    }

    isEmpty() {
        return this.front === -1;
    }

    isFull() {
        return ((this.rear + 1) % this.size) === this.front;
    }
}

πŸŽ‰ Final Thoughts

Queues are incredibly useful in real-world applications:

βœ” Task Scheduling
βœ” Operating System Processes
βœ” BFS Traversal
βœ” Messaging Systems
βœ” Rate Limiting

By understanding array-based, linked-list, stack-based, and circular queues, you now have the foundation needed for data structures & interview-level mastery.