Queue
Queue is a fundamental linear data structure that follows the FIFO (First-In-First-Out) principle—elements are added to the end (rear) and removed from the front (front), just like a real-world queue (e.g., people waiting in line). Queues are essential for tasks requiring ordered processing and are widely used in algorithms, operating systems, and distributed systems.
Core Concepts & Structure
1. Key Terminology
- Front: The first element in the queue (next to be removed).
- Rear (Tail): The last element in the queue (most recently added).
- Enqueue: Add an element to the rear of the queue.
- Dequeue: Remove and return the element from the front of the queue.
- Peek (Front): Return the front element without removing it.
- Is Empty: Check if the queue has no elements.
- Size: Return the number of elements in the queue.
2. Queue Operations (FIFO Principle)
| Operation | Description | Example (Queue: [1,2,3]) | Resulting Queue |
|---|---|---|---|
| Enqueue(4) | Add 4 to the rear | [1,2,3] → enqueue(4) | [1,2,3,4] |
| Dequeue() | Remove 1 from the front | [1,2,3,4] → dequeue() | [2,3,4] |
| Peek() | Return front element (2) | [2,3,4] → peek() | [2,3,4] (unchanged) |
| Is Empty() | Check if queue is empty (false here) | [2,3,4] → is_empty() | False |
| Size() | Return number of elements (3) | [2,3,4] → size() | 3 |
Queue Implementations (Python)
Queues can be implemented using multiple underlying data structures, each with tradeoffs in time complexity. Below are the three most common implementations:
1. Simple Implementation (List)
Python lists can be used to simulate a queue, but dequeue is inefficient (O(n) time) because removing the first element requires shifting all remaining elements left.
python
运行
class ListQueue:
def __init__(self):
self.items = [] # List to store queue elements
def enqueue(self, item):
"""Add item to the rear of the queue (O(1) time)."""
self.items.append(item)
def dequeue(self):
"""Remove and return front element (O(n) time—inefficient)."""
if self.is_empty():
return None
return self.items.pop(0) # Pop from index 0 (shifts all elements left)
def peek(self):
"""Return front element without removing it (O(1) time)."""
if self.is_empty():
return None
return self.items[0]
def is_empty(self):
"""Check if queue is empty (O(1) time)."""
return len(self.items) == 0
def size(self):
"""Return number of elements (O(1) time)."""
return len(self.items)
# Test ListQueue
if __name__ == "__main__":
q = ListQueue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
print("Queue after enqueues:", q.items) # Output: [10, 20, 30]
print("Dequeue:", q.dequeue()) # Output: 10
print("Queue after dequeue:", q.items) # Output: [20, 30]
print("Peek:", q.peek()) # Output: 20
2. Efficient Implementation (collections.deque)
Python’s built-in collections.deque (double-ended queue) is optimized for both front and rear operations. It uses a doubly linked list under the hood, making enqueue and dequeue O(1) time (optimal for queues).
This is the recommended implementation for most real-world use cases.
python
运行
from collections import deque
class DequeQueue:
def __init__(self):
self.items = deque() # Deque to store queue elements
def enqueue(self, item):
"""Add item to the rear (O(1) time)."""
self.items.append(item) # Append to end (rear)
def dequeue(self):
"""Remove and return front element (O(1) time—efficient)."""
if self.is_empty():
return None
return self.items.popleft() # Pop from front (no shifting)
def peek(self):
"""Return front element (O(1) time)."""
if self.is_empty():
return None
return self.items[0]
def is_empty(self):
"""Check if queue is empty (O(1) time)."""
return len(self.items) == 0
def size(self):
"""Return number of elements (O(1) time)."""
return len(self.items)
# Test DequeQueue
if __name__ == "__main__":
q = DequeQueue()
q.enqueue("A")
q.enqueue("B")
q.enqueue("C")
print("Queue:", list(q.items)) # Output: ['A', 'B', 'C']
print("Dequeue:", q.dequeue()) # Output: 'A'
print("Queue after dequeue:", list(q.items)) # Output: ['B', 'C']
print("Size:", q.size()) # Output: 2
3. Custom Implementation (Linked List)
A singly linked list can be used to implement a queue with O(1) enqueue and dequeue. We track both front and rear nodes to avoid traversal during dequeue.
python
运行
class Node:
"""Node class for linked list queue."""
def __init__(self, data):
self.data = data
self.next = None
class LinkedQueue:
def __init__(self):
self.front = None # Front node (next to dequeue)
self.rear = None # Rear node (last added)
self._size = 0 # Track size for O(1) access
def enqueue(self, item):
"""Add item to rear (O(1) time)."""
new_node = Node(item)
if self.is_empty():
self.front = new_node # Empty queue: front and rear point to new node
self.rear = new_node
else:
self.rear.next = new_node # Link new node to rear
self.rear = new_node # Update rear to new node
self._size += 1
def dequeue(self):
"""Remove and return front (O(1) time)."""
if self.is_empty():
return None
dequeued_data = self.front.data
self.front = self.front.next # Move front to next node
self._size -= 1
# If queue becomes empty, reset rear to None
if self.is_empty():
self.rear = None
return dequeued_data
def peek(self):
"""Return front data (O(1) time)."""
if self.is_empty():
return None
return self.front.data
def is_empty(self):
"""Check if queue is empty (O(1) time)."""
return self._size == 0
def size(self):
"""Return size (O(1) time)."""
return self._size
# Test LinkedQueue
if __name__ == "__main__":
q = LinkedQueue()
q.enqueue(100)
q.enqueue(200)
q.enqueue(300)
print("Size:", q.size()) # Output: 3
print("Dequeue:", q.dequeue()) # Output: 100
print("Peek:", q.peek()) # Output: 200
print("Size after dequeue:", q.size()) # Output: 2
Time and Space Complexity
| Implementation | Enqueue | Dequeue | Peek | Is Empty | Size | Space Complexity |
|---|---|---|---|---|---|---|
| List | O(1) | O(n) | O(1) | O(1) | O(1) | O(n) |
| deque | O(1) | O(1) | O(1) | O(1) | O(1) | O(n) |
| Linked List | O(1) | O(1) | O(1) | O(1) | O(1) | O(n) |
Key Takeaway
- Use
collections.dequefor most applications (optimal performance, simple to use). - Avoid list-based queues for large datasets (dequeue is O(n)).
- Use linked list queues only if you need full control over the underlying structure (e.g., custom extensions).
Types of Queues
Beyond the basic FIFO queue, there are specialized variants for specific use cases:
1. Priority Queue
Elements are processed based on priority (not insertion order). Higher-priority elements are dequeued first. Implemented using heaps (see Heap section for details).
Use Case: Task scheduling (OS prioritizing high-priority processes), emergency room triage.
2. Circular Queue (Ring Buffer)
A fixed-size queue where the rear wraps around to the front when the queue is full. Optimizes space by reusing empty slots left by dequeued elements.
Use Case: Buffers in I/O operations (e.g., serial ports, network sockets), streaming data processing.
3. Double-Ended Queue (Deque)
Allows enqueue/dequeue from both ends (supports FIFO and LIFO). Used as a foundation for queues and stacks.
Use Case: Sliding window algorithms, palindrome checking.
4. Blocking Queue
A thread-safe queue that blocks (pauses) when enqueuing to a full queue or dequeuing from an empty queue. Critical for concurrent programming.
Use Case: Producer-consumer patterns (e.g., multiple threads adding tasks to a queue, and workers processing them).
Pros and Cons of Queues
Pros
- Ordered Processing: FIFO principle ensures elements are processed in the order they arrive (critical for fair scheduling).
- Efficient Operations: Optimal implementations (deque/linked list) have O(1) enqueue/dequeue.
- Thread-Safe Variants: Blocking queues enable safe concurrent access (no race conditions).
- Simple to Understand: Intuitive FIFO behavior maps to real-world scenarios.
Cons
- No Random Access: Cannot efficiently access elements in the middle (must dequeue all preceding elements).
- Fixed Size (Circular Queue): Circular queues have a fixed capacity—enqueue fails if full (unless using dynamic resizing).
- Overhead (Linked List): Linked list queues have memory overhead for node pointers (vs. arrays).
Real-World Applications of Queues
- Operating Systems:
- Process scheduling (FIFO scheduling for CPU tasks).
- I/O buffering (e.g., printer queues, disk read/write buffers).
- Interrupt handling (queuing interrupts to process them in order).
- Distributed Systems:
- Message queues (e.g., RabbitMQ, Kafka) for asynchronous communication between services (e.g., order processing → inventory update → email notification).
- Load balancing (queuing requests to distribute across servers).
- Algorithms:
- Breadth-First Search (BFS) for graphs (uses a queue to explore nodes level by level).
- Cache eviction policies (FIFO cache—remove the oldest item when cache is full).
- k-way merge (merging k sorted lists using a priority queue).
- Everyday Tools:
- Ticket booking systems (queuing users to prevent overbooking).
- Chat applications (queuing messages to send in order).
- Web servers (queuing HTTP requests to process them sequentially).
Summary
Best use cases: Ordered processing, scheduling, buffering, BFS, and distributed systems.
Queue is a linear data structure following the FIFO principle (first-in, first-out).
Core operations: Enqueue (add to rear), Dequeue (remove from front), Peek (view front).
Optimal implementation: Use collections.deque (O(1) enqueue/dequeue, built-in thread safety options).
Specialized variants: Priority Queue (priority-based), Circular Queue (fixed-size), Deque (double-ended), Blocking Queue (thread-safe).
- iPhone 15 Pro Review: Ultimate Features and Specs
- iPhone 15 Pro Max: Key Features and Specifications
- iPhone 16: Features, Specs, and Innovations
- iPhone 16 Plus: Key Features & Specs
- iPhone 16 Pro: Premium Features & Specs Explained
- iPhone 16 Pro Max: Features & Innovations Explained
- iPhone 17 Pro: Features and Innovations Explained
- iPhone 17 Review: Features, Specs, and Innovations
- iPhone Air Concept: Mid-Range Power & Portability
- iPhone 13 Pro Max Review: Features, Specs & Performance
- iPhone SE Review: Budget Performance Unpacked
- iPhone 14 Review: Key Features and Upgrades
- Apple iPhone 14 Plus: The Ultimate Mid-range 5G Smartphone
- iPhone 14 Pro: Key Features and Innovations Explained
- Why the iPhone 14 Pro Max Redefines Smartphone Technology
- iPhone 15 Review: Key Features and Specs
- iPhone 15 Plus: Key Features and Specs Explained
- iPhone 12 Mini Review: Compact Powerhouse Unleashed
- iPhone 12: Key Features and Specs Unveiled
- iPhone 12 Pro: Premium Features and 5G Connectivity
- Why the iPhone 12 Pro Max is a Top Choice in 2023
- iPhone 13 Mini: Compact Powerhouse in Your Hand
- iPhone 13: Key Features and Specs Overview
- iPhone 13 Pro Review: Features and Specifications






















Leave a comment