What is a queue?
A queue is a linear data structure that follows FIFO — first in, first out. Elements join at the rear (enqueue) and leave from the front (dequeue), like people waiting in line, and both operations take O(1) time. This page animates the simple array version, including the wasted-space flaw that the circular queue fixes.
How it works
- Keep an array
Aof fixedcapacityand two indices:front = 0(the first element) andrear = -1(the last element). The queue is empty whenfront > rear. - enqueue(x): if
rear == capacity - 1there is no room at the end. Otherwise incrementrearand writeA[rear] = x. - dequeue(): if
front > rearthe queue is empty (underflow). Otherwise readx = A[front], incrementfrontand returnx. - peek() returns
A[front]without moving anything, and the size isrear - front + 1.
Worked example: enqueue 10, enqueue 20, dequeue, enqueue 30
Capacity 6, starting empty (front = 0, rear = -1):
enqueue(10): rear becomes 0 andA[0] = 10. Queue: [10].enqueue(20): rear becomes 1 andA[1] = 20. Queue: [10, 20].dequeue(): returns 10, because it arrived first; front becomes 1. Queue: [20].enqueue(30): rear becomes 2 andA[2] = 30. Queue: [20, 30] withfront = 1,rear = 2.
Slot 0 is now behind front. In this simple design neither index ever moves left again, so that slot can never be used again.
The wasted-space problem
Both indices only move right. After enough operations rear reaches the last index and enqueue reports *full* — even if dequeues have emptied most of the array. With capacity 6, enqueue six values and dequeue three: three elements remain and three slots are free, but rear == 5, so the next enqueue is refused.
There are three standard fixes:
- Compact: when you run out of room, shift the remaining elements back to index 0. Correct, but O(n).
- Circular queue: wrap the indices with
(i + 1) % capacityso freed slots at the start are reused. O(1), nothing shifts. - Linked list: keep head and tail pointers; enqueue appends at the tail and dequeue removes the head. O(1) and unbounded.
The visualizer's *Wasted space* button reproduces the problem, *Compact* shows the O(n) fix, and the Circular tab shows the O(1) one.
Queues in standard libraries
- Python:
collections.dequewithappendandpopleft, both O(1);queue.Queueadds locking for threads. Avoidlist.pop(0), which is O(n). - Java: the
Queueinterface backed byArrayDequeorLinkedList.offer,pollandpeekreturnfalseornullon failure, whileadd,removeandelementthrow exceptions. - C++:
std::queuewithpush,pop,frontandback, an adapter overstd::dequeby default.pop()returns nothing, so readfront()first. - JavaScript:
array.shift()is O(n); for large queues keep a head index into the array or use a ring buffer.
Where queues are used
- Breadth-first search and level-order traversal of trees visit nodes in the order they were discovered.
- Scheduling: CPU ready queues, round-robin time slicing, print spoolers and support-ticket lines.
- Buffering between a fast producer and a slow consumer: keyboard input, network packets, video frames and message brokers.
- Rate limiting and caches: a FIFO of timestamps or keys where the oldest entry is evicted first.
There are several kinds of queue. The simple (linear) queue on this page, the circular queue that reuses space, the deque that works at both ends, and the priority queue, which removes the highest-priority element instead of the oldest — usually a binary heap, so it is not FIFO at all.
Common mistakes and interview questions
- Testing emptiness with
front == rearin this design: a queue with one element also hasfront == rear. Empty isfront > rear. - Forgetting that a linear array queue can refuse an enqueue while it still has free slots.
- Computing the size as
rear - frontinstead ofrear - front + 1. - Using
list.pop(0)orarray.shift()inside a loop and turning an O(n) algorithm into O(n²).
Popular interview tasks: implement a queue with two stacks, implement a stack with queues, design a circular queue (LeetCode 622), shortest path in a grid or "rotting oranges" with BFS, and the first non-repeating character in a stream.
Time and space complexity
| Case | Time | Space | Why |
|---|---|---|---|
| enqueue | O(1) | O(1) | Writes one slot after rear. |
| dequeue | O(1) | O(1) | Moves front one step; nothing shifts. |
| peek / size / isEmpty | O(1) | O(1) | Index arithmetic only. |
| compact | O(n) | O(1) | Moves every remaining element back to index 0. |
| dequeue via list.pop(0) | O(n) | O(1) | Each remaining element shifts one place left. |
Queue in Python
class Queue:
"""FIFO queue in a plain array: both indices only move right."""
def __init__(self, capacity):
self.A = [None] * capacity
self.capacity = capacity
self.front = 0 # first element
self.rear = -1 # last element; empty when front > rear
def enqueue(self, x):
if self.rear == self.capacity - 1:
raise IndexError("Queue full") # even if front > 0!
self.rear = self.rear + 1
self.A[self.rear] = x
def dequeue(self):
if self.front > self.rear:
raise IndexError("Queue empty")
x = self.A[self.front]
self.front = self.front + 1 # this slot is lost for good
return x
def peek(self):
if self.front > self.rear:
raise IndexError("Queue empty")
return self.A[self.front]
def compact(self):
"""Fix #1 for wasted space: shift everything back to index 0, O(n)."""
n = self.rear - self.front + 1
for i in range(n):
self.A[i] = self.A[self.front + i]
self.front = 0
self.rear = n - 1
def clear(self):
self.front = 0
self.rear = -1
def is_empty(self):
return self.front > self.rear
def size(self):
return self.rear - self.front + 1
# q = Queue(6); q.enqueue(10); q.enqueue(20); q.dequeue() -> 10The visualizer above shows the same code in Python, C++, Java and JavaScript.
Frequently asked questions
Is a queue FIFO or LIFO?
A queue is FIFO: the element that has waited longest leaves first. LIFO describes a stack.
What is the difference between enqueue and dequeue?
Enqueue adds an element at the rear of the queue; dequeue removes and returns the element at the front. Both are O(1).
Why does a linear array queue say it is full when it has empty slots?
Because front and rear only move right, slots before front are never revisited. A circular queue wraps the indices around so those slots are reused.
Why is list.pop(0) slow in Python?
Removing the first element shifts every remaining element one place left, which is O(n). collections.deque.popleft() is O(1).
Is a priority queue a queue?
Only by name: it removes the element with the highest priority rather than the oldest one, so it is not FIFO. It is usually a binary heap with O(log n) insert and remove.
What are queue overflow and underflow?
Overflow is enqueuing into a full queue; underflow is dequeuing from an empty one. Check isFull() or isEmpty() first, or use a structure that grows.
Keep learning
- Stack & Queue VisualizerStack and queue visualizer: animate push, pop, enqueue and dequeue, compare LIFO with FIFO, and step through circular queues, deques and stack applications.
- 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.
- Deque VisualizerDeque visualizer: push and pop at both the front and back of a double-ended queue on a circular array, each in O(1), and see how it acts as a stack or a queue.
- 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).
- Binary Heap VisualizerBinary heap visualizer: watch sift-up and sift-down in the tree and array side by side. Learn min-heap vs max-heap and O(log n) insert and extract, with code.
- 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