Queue
Learn how queues work — FIFO order, enqueue and dequeue operations, and why Python lists make poor queues.
Queue
A queue is a collection where elements are added at one end and removed from the other. It follows FIFO order — First In, First Out. The first item added is the first one removed.
Think of a queue like people waiting in line at a coffee shop. The first person in line is served first. New people join at the back.
enqueue(4) front → [4] ← back
enqueue(7) front → [4, 7] ← back
enqueue(2) front → [4, 7, 2] ← back
dequeue() → 4 front → [7, 2] ← backCore operations
| Operation | What it does | Time |
|---|---|---|
enqueue(x) | Add x to the back | O(1) |
dequeue() | Remove and return the front element | O(1) with deque |
peek() / front() | Look at the front without removing | O(1) |
is_empty() | Check if the queue has no elements | O(1) |
Why not use a Python list?
queue = []
queue.append(10) # enqueue — O(1), fine
queue.append(20)
queue.append(30)
front = queue.pop(0) # dequeue — O(n)! Everything shifts leftlist.pop(0) removes the first element — but every remaining element has to shift left by one position. That is O(n), not O(1). For a queue with frequent dequeue operations, this makes a Python list a poor choice.
The correct implementation — collections.deque
from collections import deque
class Queue:
def __init__(self):
self.items = deque()
def enqueue(self, item):
self.items.append(item) # add to back — O(1)
def dequeue(self):
if self.is_empty():
raise IndexError("dequeue from empty queue")
return self.items.popleft() # remove from front — O(1)
def peek(self):
if self.is_empty():
raise IndexError("peek from empty queue")
return self.items[0]
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
q = Queue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
print(q.peek()) # 10
print(q.dequeue()) # 10
print(q.dequeue()) # 20
print(q.size()) # 1deque (double-ended queue) is implemented as a doubly linked list internally — both ends support O(1) insert and remove.
Types of queues
Simple queue — strict FIFO, as shown above.
Circular queue — when the back reaches the end of a fixed-size buffer, it wraps around to the beginning. Used in buffering — like a circular buffer in audio/video streaming.
Priority queue — elements are dequeued based on priority, not insertion order. Implemented with a heap. Covered in the trees section.
Double-ended queue (deque) — allows insert and remove at both ends. Python's deque supports this directly.
from collections import deque
d = deque()
d.append(10) # add to back
d.appendleft(5) # add to front
d.pop() # remove from back
d.popleft() # remove from frontReal use cases
Task scheduling — operating systems queue processes waiting for CPU time.
Breadth-first search — BFS uses a queue to explore level by level (see the graphs section).
Print queue — print jobs are processed in the order they were submitted.
Message queues — systems like RabbitMQ and Kafka process messages in order.
Request handling — web servers queue incoming requests to process them in order.
Stack vs Queue — side by side
| Stack | Queue | |
|---|---|---|
| Order | LIFO | FIFO |
| Add | push (top) | enqueue (back) |
| Remove | pop (top) | dequeue (front) |
| Real analogy | Pile of plates | Line at a store |
| Python structure | list (append/pop) | deque (append/popleft) |
| Used in | DFS, undo/redo, call stack | BFS, task scheduling |
Complexity
| Operation | Time (with deque) | Time (with list) |
|---|---|---|
| Enqueue | O(1) | O(1) |
| Dequeue | O(1) | O(n) |
| Peek | O(1) | O(1) |
Always use deque for queues in Python — never a plain list.