DSA Notes
A thorough introduction to queues — the FIFO (First In, First Out) data structure. Learn the queue model, all operations with complexity, types of queues, real-world applications, comparison with stacks, and when to use queues in algorithms.
Introduction
A queue is a linear data structure that follows FIFO (First In, First Out) ordering — the first element added is the first one removed.
Think of a real queue (line) at a ticket counter: the first person to join the line is the first person served. New people join at the back, and service happens at the front. No one cuts in line.
This contrasts with a stack (LIFO): where the *last* added is the *first* removed (like a stack of plates).
Queues are the foundation of Breadth-First Search (BFS), CPU scheduling, print spooling, network packet management, and event-driven programming.
Queue Operations
| Operation | Description | Time |
|---|---|---|
enqueue(x) | Add element x to the rear | O(1) |
dequeue() | Remove and return front element | O(1) |
front() / peek() | View front element without removing | O(1) |
rear() | View rear element without removing | O(1) |
is_empty() | True if no elements | O(1) |
size() | Number of elements | O(1) |
Types of Queues
1. Simple Queue (Linear Queue)
Standard FIFO. Elements enqueue at rear, dequeue at front.
2. Circular Queue
The rear wraps around to the front when the array is full, reusing space freed by dequeued elements. Avoids the "wasted space" problem of linear array queues.
3. Double-Ended Queue (Deque)
Elements can be added or removed from both ends. Combines stack and queue behavior.
4. Priority Queue
Each element has a priority. The element with the highest priority is dequeued first, regardless of insertion order. Implemented with a heap.
Simple Queue Implementation
Why use deque and NOT list:
# WRONG — O(n) dequeue
queue = []
queue.append(item) # O(1) enqueue
queue.pop(0) # O(n) dequeue — shifts all elements!
# CORRECT — O(1) dequeue
from collections import deque
queue = deque()
queue.append(item) # O(1) enqueue
queue.popleft() # O(1) dequeueReal-World Applications
1. Breadth-First Search (BFS)
BFS is the most important algorithm that uses a queue. It explores a graph level by level — all nodes at distance 1, then all at distance 2, etc.
2. CPU Process Scheduling (FIFO / Round-Robin)
class CPUScheduler:
def __init__(self):
self.ready_queue = Queue()
def add_process(self, pid, burst_time):
self.ready_queue.enqueue((pid, burst_time))
def run_next(self):
if not self.ready_queue.is_empty():
pid, burst = self.ready_queue.dequeue()
print(f"Running Process P{pid} for {burst} units")3. Print Spooler
class PrintSpooler:
"""Documents print in the order they were submitted."""
def __init__(self):
self._queue = Queue()
def submit_document(self, document_name):
self._queue.enqueue(document_name)
print(f"Queued: {document_name}")
def print_next(self):
if not self._queue.is_empty():
doc = self._queue.dequeue()
print(f"Printing: {doc}")4. Message Queue (Producer-Consumer)
import threading
class MessageQueue:
"""Thread-safe queue for producer-consumer pattern."""
def __init__(self):
from queue import Queue as ThreadQueue
self._q = ThreadQueue() # Python's thread-safe Queue
def produce(self, message):
self._q.put(message) # Blocks if queue is full
def consume(self):
return self._q.get() # Blocks until message availableQueue vs Stack — When to Use Which
| Use Queue (FIFO) When | Use Stack (LIFO) When |
|---|---|
| Processing order matters (oldest first) | Most recent item is relevant |
| BFS traversal | DFS traversal |
| Level-by-level tree traversal | Backtracking |
| Task scheduling | Undo/Redo |
| Producer-consumer systems | Expression evaluation |
| Printing, messaging, buffering | Function call management |
Python's Queue Support
# 1. collections.deque — most common for manual queue implementation
from collections import deque
q = deque()
q.append(1) # enqueue at right
q.appendleft(0) # enqueue at left
q.popleft() # dequeue from left
q.pop() # dequeue from right
# 2. queue.Queue — thread-safe, for concurrent programs
from queue import Queue, LifoQueue, PriorityQueue
q = Queue(maxsize=10) # Blocking queue, optional max size
q.put(item) # enqueue (blocks if full with maxsize)
q.get() # dequeue (blocks if empty)
q.qsize() # Size
# 3. queue.LifoQueue — stack using queue interface
lq = LifoQueue()
lq.put(1); lq.put(2)
lq.get() # Returns 2 (LIFO)
# 4. queue.PriorityQueue — min-heap based priority queue
pq = PriorityQueue()
pq.put((priority, item))
pq.get() # Returns (lowest_priority, item)Summary
The queue is the FIFO data structure:
- Enqueue: Add to rear → O(1)
- Dequeue: Remove from front → O(1)
- All core operations: O(1)
- Never use Python list for queue — use
collections.deque
Types: Simple, Circular, Deque (double-ended), Priority Queue
Real-world uses:
- BFS graph traversal (most important)
- CPU scheduling
- Print spooling and job queues
- Message passing between processes
- Network packet buffering
*Next Lesson: Queue Implementation — Complete implementations using arrays, linked lists, and two stacks.*
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Queue — Complete Introduction to the FIFO Data Structure.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Data Structures & Algorithms topic.
Search Terms
data-structures-algorithms, data structures & algorithms, data, structures, algorithms, queues, queue, introduction
Related Data Structures & Algorithms Topics