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.
Both Stack and Queue store a collection of items. The key difference is how items are removed.
Like a stack of plates β you always take the top one.
β push/pop from here
Like a line at a shop β first person served first.
β dequeue enqueue β
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; } }
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; } }
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")
Queue: enqueue("D")
Front β β Rear
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"
Queue: dequeue() β "A"
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]
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(); };
getAll() returns a plain array copy which can be
serialized to JSON. On reload, load() restores it back.
| 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) |