Imagine you have tasks arriving in order and you want to process them in the same order they arrive. Why is a queue better than a stack for this?
Think about the order tasks come in and the order they should be done.
A queue follows first-in, first-out (FIFO) order, so tasks are handled in the order they arrive. A stack follows last-in, first-out (LIFO), so the newest task is handled first, which is not suitable for scheduling tasks that must be done in arrival order.
Consider this JavaScript queue implemented with an array. What will be printed after the operations?
class Queue { constructor() { this.items = []; } enqueue(element) { this.items.push(element); } dequeue() { return this.items.shift(); } print() { console.log(this.items.join(' -> ') + ' -> null'); } } const q = new Queue(); q.enqueue(10); q.enqueue(20); q.enqueue(30); q.dequeue(); q.enqueue(40); q.print();
Remember dequeue removes the first element added.
After enqueueing 10, 20, 30, the queue is [10, 20, 30]. Dequeue removes 10, leaving [20, 30]. Enqueue 40 adds it to the end: [20, 30, 40]. Printing shows '20 -> 30 -> 40 -> null'.
This code tries to implement a queue using an array but has a bug. What problem will happen when running it?
class Queue { constructor() { this.items = []; } enqueue(element) { this.items.push(element); } dequeue() { return this.items.pop(); } } const q = new Queue(); q.enqueue(1); q.enqueue(2); q.enqueue(3); console.log(q.dequeue()); console.log(q.dequeue());
Check what push and pop do to the array ends.
Using push to add at the end and pop to remove from the end causes the queue to behave like a stack (LIFO). The newest element is removed first, not the oldest.
Choose the scenario where using a queue data structure is the best fit.
Think about who should be served first in each scenario.
Serving customers in order of arrival is a classic FIFO problem, perfectly modeled by a queue. Undo actions use a stack (LIFO). Browser history navigation uses stacks. Depth-first search uses a stack, not a queue.
Given this JavaScript queue code, what is printed at the end?
class Queue { constructor() { this.items = []; } enqueue(element) { this.items.push(element); } dequeue() { if (this.items.length === 0) return null; return this.items.shift(); } print() { console.log(this.items.join(' -> ') + ' -> null'); } } const q = new Queue(); q.enqueue('a'); q.enqueue('b'); q.dequeue(); q.enqueue('c'); q.enqueue('d'); q.dequeue(); q.enqueue('e'); q.print();
Track each enqueue and dequeue step carefully.
Operations step by step:
enqueue 'a' -> [a]
enqueue 'b' -> [a, b]
dequeue removes 'a' -> [b]
enqueue 'c' -> [b, c]
enqueue 'd' -> [b, c, d]
dequeue removes 'b' -> [c, d]
enqueue 'e' -> [c, d, e]
Print shows 'c -> d -> e -> null'.
