What are stacks and queues?
A stack and a queue are linear collections that only let you add and remove items at fixed ends. A stack is LIFO (last in, first out): push and pop both happen at the top, while a queue is FIFO (first in, first out): enqueue at the rear, dequeue at the front. Implemented well, every one of these operations takes O(1) time.
Stack vs queue at a glance
- Removal order: a stack returns the newest item first (LIFO); a queue returns the oldest item first (FIFO).
- Where changes happen: a stack inserts and removes at the same end, the top; a queue inserts at the rear and removes at the front.
- Operations: stack —
push,pop,peek; queue —enqueue,dequeue,peek(orfront). - Array bookkeeping: a stack needs one index (
top); a queue needs two (frontandrear), which is why array queues need the circular trick to reuse space. - Everyday picture: a pile of plates versus a line at a ticket counter.
- Typical algorithms: depth-first search, backtracking and expression parsing use stacks; breadth-first search, scheduling and buffering use queues.
Put 1, 2, 3 into both: popping the stack gives 3, 2, 1 (reversed), dequeuing the queue gives 1, 2, 3 (preserved). That one property usually decides which a problem needs — "most recent first" points to a stack, "in arrival order" to a queue.
The four structures in this visualizer
- Stack: an array plus a
topindex. Pushing onto a full array is an overflow; popping an empty one is an underflow. - Linear queue: an array whose
frontandrearonly move right. It is simple, but slots freed by dequeue are never reused — the wasted-space problem. - Circular queue: the same array with indices that wrap around using
% capacity, so every slot is reused and both operations stay O(1). - Deque: a double-ended queue that inserts and removes at both ends in O(1). Use one end and it is a stack; use both and it is a queue.
Classic stack applications
Stacks shine whenever the most recent unfinished thing has to be finished first. The Applications tab animates the four problems that appear in nearly every data-structures course and coding interview:
- Balanced parentheses: push each opening bracket and match every closing bracket against the top.
- Infix to postfix: the shunting-yard algorithm parks operators on a stack until precedence lets them out.
- Postfix evaluation: push numbers and let each operator pop its two operands.
- Next greater element: a monotonic stack answers "first larger value to the right" for every element in O(n).
Outside the classroom the same idea runs your program's call stack (each function call pushes a frame), the undo history of an editor, the back button of a browser and iterative depth-first search.
Where queues show up
- Breadth-first search and level-order tree traversal process nodes in the order they were discovered.
- Operating systems keep ready queues of processes, and printers keep a print queue.
- Devices — keyboards, sound cards, network cards — buffer data in ring buffers, which are circular queues.
- Message queues such as Kafka, RabbitMQ or SQS decouple fast producers from slow consumers.
- Deques power the sliding-window maximum trick and 0-1 BFS.
A priority queue is the odd one out: it removes the highest-priority item rather than the oldest, so it is not FIFO. It is normally built on a binary heap.
Stacks and queues in real code
- Python: a
listis a fine stack (append,pop,s[-1]). For a queue usecollections.deque(append,popleft) —list.pop(0)is O(n) because every remaining element shifts. - Java: prefer
ArrayDequefor both (push/popandoffer/poll). The legacyStackclass is synchronized and extendsVector. - C++:
std::stackandstd::queueare adapters overstd::deque;pop()returns nothing, so readtop()orfront()first. - JavaScript: arrays work as stacks (
push/pop), butshift()is O(n), so large queues should keep a head index or use a ring buffer.
Interviewers love combining the two: implement a queue with two stacks (amortized O(1) per operation), a stack with queues, or a "min stack" that reports its minimum in O(1) by keeping a second stack of running minimums.
Time and space complexity
| Case | Time | Space | Why |
|---|---|---|---|
| Stack push / pop / peek | O(1) | O(n) | Only the top is touched; with a growable array, push is amortized O(1). |
| Queue enqueue / dequeue | O(1) | O(n) | Circular array or linked list: two indices move, nothing shifts. |
| Deque at either end | O(1) | O(n) | Same circular array, with front allowed to step backwards. |
| Search for a value | O(n) | O(1) | Neither structure is built for lookup — you scan. |
| list.pop(0) / array.shift() | O(n) | O(1) | Removing the first element of an array shifts all the others. |
Stack & Queue in Python
from collections import deque
stack = [] # LIFO: use the end of a list
stack.append(1) # push
stack.append(2)
stack.append(3)
print(stack.pop()) # 3 - the last one in comes out first
print(stack[-1]) # 2 - peek at the top
queue = deque() # FIFO: O(1) at both ends
queue.append(1) # enqueue at the rear
queue.append(2)
queue.append(3)
print(queue.popleft()) # 1 - the first one in comes out first
print(queue[0]) # 2 - peek at the frontThe visualizer above shows the same code in Python, C++, Java and JavaScript.
Frequently asked questions
What is the difference between a stack and a queue?
A stack removes the most recently added item first (LIFO), while a queue removes the oldest item first (FIFO). A stack adds and removes at the same end; a queue adds at the rear and removes at the front.
Is a stack LIFO or FIFO?
A stack is LIFO — last in, first out. A queue is FIFO — first in, first out.
Which data structure does BFS use, and which does DFS use?
Breadth-first search uses a queue, so it explores nodes in order of distance from the start. Depth-first search uses a stack, either explicitly or through the recursion call stack.
How do you implement a queue using two stacks?
Push new items onto an *in* stack. To dequeue, pop from an *out* stack; when it is empty, first move everything from *in* to *out*, which reverses the order. Each item moves at most once, so every operation is amortized O(1).
Why use collections.deque instead of a list for a queue in Python?
deque.popleft() is O(1), while list.pop(0) is O(n) because every remaining element shifts left. For a stack, a plain list with append and pop is fine.
Are push and pop always O(1)?
In a linked-list stack, yes. In a dynamic array, push is amortized O(1): an occasional resize copies all n items, but averaged over many pushes the cost per push is constant.
Keep learning
- Stack VisualizerInteractive stack visualizer: watch push, pop and peek move the top pointer of an array stack, see overflow and underflow happen, and learn why each is O(1).
- Queue VisualizerInteractive queue visualizer: watch enqueue and dequeue move the front and rear of an array queue, and see the wasted-space problem that circular queues fix.
- Circular Queue VisualizerCircular queue visualizer: watch front and rear wrap around a ring buffer with (i + 1) % capacity, and learn how to tell a full queue from an empty one.
- Infix to Postfix ConverterConvert infix to postfix step by step with the shunting-yard algorithm: see the operator stack, precedence and associativity, and the output after every token.
- Linked List VisualizerInteractive linked list visualizer: watch every pointer change as you insert, delete, search and reverse singly, doubly and circular lists, with code and costs.
- Graph Algorithm VisualizerInteractive graph algorithm visualizer: draw or generate a graph and step through BFS, DFS, Dijkstra, Bellman-Ford, Kruskal, Prim, topological sort and SCCs.
Last updated