Tech Deep Dive

How the Stack & Queue Page Works

This page breaks down the Stack & Queue workshop step by step. You'll see the real code from this project and learn how each data structure works under the hood.

🧠 Stack vs Queue β€” What's the Difference?

Both Stack and Queue store a collection of items. The key difference is how items are removed.

πŸ₯ž

Stack β€” LIFO

Last In, First Out

Like a stack of plates β€” you always take the top one.

"C" Top
"B"
"A"

↑ push/pop from here

πŸšΆβ€β™‚οΈ

Queue β€” FIFO

First In, First Out

Like a line at a shop β€” first person served first.

"A" Front
β†’
"B"
β†’
"C" Rear

← dequeue   enqueue β†’

Step-by-Step: How The Code Works

Build the Stack Class

A Stack uses a simple array internally. push() adds to the end and pop() removes from the end β€” LIFO. top() peeks at the top without removing.

// From script.js β€” The Stack class
class Stack {
    constructor() { this.items = []; }

    push(val)  { this.items.push(val); }
    pop()      { return this.items.pop(); }
    top()      { return this.items[this.items.length - 1]; }
    clear()    { this.items = []; }
    isEmpty()  { return this.items.length === 0; }
}
πŸ’‘ Think of it like this: A stack of books β€” you can only add or remove from the top.

Build the Queue Class

A Queue removes from the front using shift(). enqueue() adds to the rear, dequeue() removes from the front β€” FIFO. front() and rear() peek at both ends.

// From script.js β€” The Queue class
class Queue {
    constructor() { this.items = []; }

    enqueue(val) { this.items.push(val); }
    dequeue()    { return this.items.shift(); }
    front()      { return this.items[0]; }
    rear()       { return this.items[this.items.length - 1]; }
    clear()      { this.items = []; }
    isEmpty()    { return this.items.length === 0; }
}
πŸ’‘ Think of it like this: A queue at a ticket booth β€” the first person in line gets served first.

Push (Stack) vs Enqueue (Queue)

Both add an item. The addToBoth() function lets you add the same value to both structures at once to compare behavior.

// From script.js β€” add to both
window.addToBoth = () => {
    const val = getInput();
    if (!val) return;
    stack.push(val);       // β†’ TOP
    queue.enqueue(val);    // β†’ REAR
    save(); render();
};

Stack: push("D")

D ✨ ← Top
C
B
A

Queue: enqueue("D")

A
β†’
B
β†’
C
β†’
D ✨

Front ← β†’ Rear

Pop (Stack) vs Dequeue (Queue)

pop() removes from the top (last added), while dequeue() removes from the front (first added). Same data, different removal order.

// From script.js β€” removing items
window.popStack = () => {
    if (stack.isEmpty()) return showToast("Stack Empty", "error");
    stack.pop();    // removes TOP
    save(); render();
};

window.dequeueQueue = () => {
    if (queue.isEmpty()) return showToast("Queue Empty", "error");
    queue.dequeue(); // removes FRONT
    save(); render();
};

Stack: pop() β†’ "D"

D ❌
C ← Top
B
A

Queue: dequeue() β†’ "A"

A ❌
β†’
B Front
β†’
C
β†’
D Rear

Peek β€” Look Without Removing

top() shows the stack's top, front() the queue's first item, rear() the last. None remove the item.

// From script.js β€” peek operations
window.peekStack = () =>
    stack.isEmpty()
        ? showToast("Stack Empty", "error")
        : showToast(`Top: ${stack.top()}`);

window.peekQueueFront = () =>
    queue.isEmpty()
        ? showToast("Queue Empty", "error")
        : showToast(`Front: ${queue.front()}`);

window.peekQueueRear = () =>
    queue.isEmpty()
        ? showToast("Queue Empty", "error")
        : showToast(`Rear: ${queue.rear()}`);

Visual: Peeking at [A, B, C]

stack.top()
"C"
queue.front()
"A"
queue.rear()
"C"

Persistence with localStorage

Every operation saves data to localStorage. On page reload, load() restores the saved state into both classes.

// From script.js β€” save & load
const STORAGE_KEY = "sq_data";

const save = () => {
    localStorage.setItem(STORAGE_KEY, JSON.stringify({
        stack: stack.getAll(),
        queue: queue.getAll()
    }));
};

const load = () => {
    const data = JSON.parse(localStorage.getItem(STORAGE_KEY));
    if (data) {
        stack.load(data.stack || []);
        queue.load(data.queue || []);
    }
    render();
};
πŸ’‘ Why this works: getAll() returns a plain array copy which can be serialized to JSON. On reload, load() restores it back.

πŸ“‹ Operations Summary

Structure Operation Speed
Stack push(val) O(1)
pop() O(1)
top() O(1)
Queue enqueue(val) O(1)
dequeue() O(n)
front() O(1)
rear() O(1)
Workshop: Stack & Queue β€” CSI105T Data Structures Β· Author: 68037294 Raksit Phothong