Queue
A queue is a First-In-First-Out (FIFO) data structure where elements are added at one end (rear) and removed from the other end (front). It follows the principle that the first element added is the first one to be removed.
Features
- FIFO ordering - First In, First Out access pattern
- Efficient operations - O(1) enqueue, dequeue, and peek operations
- Dynamic size - automatically grows and shrinks as needed
- Memory efficient - uses singly linked list for optimal memory usage
- Type safe - generic implementation with type checking
- Iterator support - can iterate from front to rear
- Utility operations - search, count, reverse, and copy functionality
Time Complexities
| Operation | Time Complexity | Description |
|---|---|---|
| Enqueue | O(1) | Add element to rear |
| Dequeue | O(1) | Remove element from front |
| Front | O(1) | View front element |
| Rear | O(1) | View rear element |
| Search | O(n) | Find element position |
| Count | O(n) | Count occurrences |
| Clear | O(1) | Remove all elements |
| Copy | O(n) | Create shallow copy |
| Reverse | O(n) | Reverse queue order |
| Size/Length | O(1) | Get number of elements |
Space Complexity: O(n) where n is the number of elements
Basic Usage
Creating and Initializing
from algo.data_structs.stacks_queues.queue import Queue
# Create empty queue
queue = Queue()
# Check if empty
print(queue.is_empty()) # True
print(len(queue)) # 0
print(queue.size()) # 0
# Queue is generic - can specify type
int_queue = Queue[int]()
str_queue = Queue[str]()
Adding Elements (Enqueue)
# Enqueue individual elements
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(len(queue)) # 3
print(queue.front()) # 1 (first element added)
print(queue.rear()) # 3 (last element added)
# Enqueue multiple elements using extend
queue.extend([4, 5, 6])
print(queue.rear()) # 6 (last element added)
print(len(queue)) # 6
# Extend with different iterables
queue.extend((7, 8)) # Tuple
queue.extend([9, 10]) # List
print(queue.to_list()) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (front to rear)
Viewing Elements
# Peek at front element without removing
front_element = queue.front()
print(front_element) # 1
print(len(queue)) # Still same size
# Peek at rear element without removing
rear_element = queue.rear()
print(rear_element) # 10
# Check if queue contains element
print(5 in queue) # True
print(99 in queue) # False
# Convert to list (front to rear order)
elements = queue.to_list()
print(elements) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Removing Elements (Dequeue)
# Dequeue elements one by one (FIFO order)
dequeued = queue.dequeue()
print(dequeued) # 1 (first element added)
print(len(queue)) # 9
# Dequeue multiple elements
results = []
for _ in range(3):
results.append(queue.dequeue())
print(results) # [2, 3, 4]
# Dequeue until empty
while not queue.is_empty():
element = queue.dequeue()
print(f"Dequeued: {element}")
print(queue.is_empty()) # True
Clearing the Queue
# Add some elements
queue.extend([1, 2, 3, 4, 5])
print(len(queue)) # 5
# Clear all elements
queue.clear()
print(len(queue)) # 0
print(queue.is_empty()) # True
Search and Count Operations
Finding Elements
queue = Queue()
queue.extend([1, 2, 3, 2, 4, 2]) # [1, 2, 3, 2, 4, 2] (front to rear)
# Search returns position from front (0-based)
print(queue.search(1)) # 0 (front element)
print(queue.search(2)) # 1 (first occurrence of 2)
print(queue.search(3)) # 2 (third position from front)
print(queue.search(4)) # 4 (fifth position from front)
print(queue.search(99)) # -1 (not found)
# Check membership
print(2 in queue) # True
print(99 in queue) # False
Counting Elements
# Count occurrences of elements
print(queue.count(2)) # 3 (appears 3 times)
print(queue.count(1)) # 1 (appears once)
print(queue.count(99)) # 0 (not present)
# Count all elements
total_elements = len(queue)
print(total_elements) # 6
Iteration and Traversal
queue = Queue()
queue.extend(['apple', 'banana', 'cherry', 'date'])
# Iterate from front to rear
print("Queue contents (front to rear):")
for item in queue:
print(item) # apple, banana, cherry, date
# Convert to list for processing
items = list(queue)
print(items) # ['apple', 'banana', 'cherry', 'date']
# Enumerate with position
for i, item in enumerate(queue):
print(f"Position {i}: {item}")
Working with Different Types
String Elements
words = Queue()
words.enqueue("hello")
words.enqueue("world")
words.enqueue("python")
print(words.front()) # "hello"
print("world" in words) # True
print(words.count("hello")) # 1
Numeric Elements
numbers = Queue()
numbers.extend([1, 2, 3, 4, 5])
numbers.enqueue(3.14)
numbers.enqueue(42)
print(numbers.front()) # 1
print(3.14 in numbers) # True
print(len(numbers)) # 7
Mixed Types
mixed = Queue()
mixed.enqueue("string")
mixed.enqueue(42)
mixed.enqueue([1, 2, 3]) # Lists can be stored
mixed.enqueue(True)
print(mixed.front()) # "string"
print(42 in mixed) # True
print(len(mixed)) # 4
Custom Objects
class Task:
def __init__(self, name: str, priority: int):
self.name = name
self.priority = priority
def __eq__(self, other):
return isinstance(other, Task) and self.name == other.name
def __str__(self):
return f"Task({self.name}, priority={self.priority})"
tasks = Queue()
task1 = Task("Write code", 1)
task2 = Task("Test code", 2)
task3 = Task("Deploy", 3)
tasks.enqueue(task1)
tasks.enqueue(task2)
tasks.enqueue(task3)
print(tasks.front()) # Task(Write code, priority=1)
print(task1 in tasks) # True
print(len(tasks)) # 3
Queue Manipulation
Copying Queues
original = Queue()
original.extend([1, 2, 3, 4, 5])
# Create a copy
copy_queue = original.copy()
# Verify they have same contents
print(copy_queue.to_list() == original.to_list()) # True
print(len(copy_queue) == len(original)) # True
# Verify they're independent
original.enqueue(6)
print(len(original)) # 6
print(len(copy_queue)) # 5 (unchanged)
copy_queue.enqueue(99)
print(99 in original) # False
print(99 in copy_queue) # True
Reversing Queues
queue = Queue()
queue.extend([1, 2, 3, 4, 5])
print(queue.to_list()) # [1, 2, 3, 4, 5] (front to rear)
# Reverse the queue
queue.reverse()
print(queue.to_list()) # [5, 4, 3, 2, 1] (front to rear)
print(queue.front()) # 5 (was rear, now front)
print(queue.rear()) # 1 (was front, now rear)
String Representation
# Empty queue
empty_queue = Queue()
print(str(empty_queue)) # Queue([])
# Non-empty queue
queue = Queue()
queue.extend([1, 2, 3])
print(str(queue)) # Queue([1 <- 2 <- 3] <- rear)
# Detailed representation for debugging
print(repr(queue)) # Queue(size=3, front=1, rear=3)
Error Handling
queue = Queue()
# Safe operations on empty queue
print(queue.is_empty()) # True
print(len(queue)) # 0
print(queue.search(42)) # -1
print(queue.count(42)) # 0
print(42 in queue) # False
# Operations that raise errors on empty queue
try:
queue.dequeue()
except IndexError as e:
print(f"Error: {e}") # Error: Cannot dequeue from empty queue
try:
queue.front()
except IndexError as e:
print(f"Error: {e}") # Error: Cannot peek front of empty queue
try:
queue.rear()
except IndexError as e:
print(f"Error: {e}") # Error: Cannot peek rear of empty queue
Common Patterns
Building from Iterables
# From list
queue = Queue()
queue.extend([1, 2, 3, 4, 5])
# From tuple
queue2 = Queue()
queue2.extend((1, 2, 3))
# From range
queue3 = Queue()
queue3.extend(range(10))
# From another queue
queue4 = Queue()
queue4.extend(queue) # Copy elements from queue
FIFO Processing
# Process items in order
items = ["first", "second", "third", "fourth"]
queue = Queue()
# Load items
for item in items:
queue.enqueue(item)
# Process in FIFO order
processed = []
while not queue.is_empty():
item = queue.dequeue()
processed.append(f"Processed: {item}")
print(processed)
# ['Processed: first', 'Processed: second', 'Processed: third', 'Processed: fourth']
Task Scheduling
class TaskScheduler:
def __init__(self):
self.task_queue = Queue()
self.completed_tasks = []
def add_task(self, task_name: str):
"""Add a task to the queue."""
self.task_queue.enqueue(task_name)
print(f"Added task: {task_name}")
def process_next_task(self):
"""Process the next task in the queue."""
if not self.task_queue.is_empty():
task = self.task_queue.dequeue()
self.completed_tasks.append(task)
print(f"Processing task: {task}")
return task
else:
print("No tasks to process")
return None
def show_queue_status(self):
"""Show current queue status."""
print(f"Tasks in queue: {len(self.task_queue)}")
print(f"Completed tasks: {len(self.completed_tasks)}")
if not self.task_queue.is_empty():
print(f"Next task: {self.task_queue.front()}")
# Usage
scheduler = TaskScheduler()
scheduler.add_task("Send email")
scheduler.add_task("Update database")
scheduler.add_task("Generate report")
scheduler.show_queue_status()
scheduler.process_next_task()
scheduler.process_next_task()
scheduler.show_queue_status()
Producer-Consumer Pattern
class Buffer:
def __init__(self, max_size: int = 10):
self.queue = Queue()
self.max_size = max_size
def produce(self, item):
"""Producer adds items to buffer."""
if len(self.queue) < self.max_size:
self.queue.enqueue(item)
print(f"Produced: {item} (buffer size: {len(self.queue)})")
return True
else:
print(f"Buffer full! Cannot produce: {item}")
return False
def consume(self):
"""Consumer takes items from buffer."""
if not self.queue.is_empty():
item = self.queue.dequeue()
print(f"Consumed: {item} (buffer size: {len(self.queue)})")
return item
else:
print("Buffer empty! Nothing to consume")
return None
def peek_next(self):
"""Peek at next item to be consumed."""
if not self.queue.is_empty():
return self.queue.front()
return None
# Usage
buffer = Buffer(max_size=3)
# Producer adds items
for i in range(5):
buffer.produce(f"item_{i}")
# Consumer processes items
for _ in range(3):
buffer.consume()
# Producer adds more
buffer.produce("item_5")
buffer.produce("item_6")
Breadth-First Search
def bfs_traversal(graph, start_node):
"""Perform breadth-first search traversal using a queue."""
visited = set()
queue = Queue()
result = []
queue.enqueue(start_node)
visited.add(start_node)
while not queue.is_empty():
current_node = queue.dequeue()
result.append(current_node)
# Add unvisited neighbors to queue
for neighbor in graph.get(current_node, []):
if neighbor not in visited:
visited.add(neighbor)
queue.enqueue(neighbor)
return result
# Example graph representation
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
# Perform BFS starting from 'A'
traversal_order = bfs_traversal(graph, 'A')
print(f"BFS traversal: {traversal_order}")
# Output: ['A', 'B', 'C', 'D', 'E', 'F'] (or similar order)
Practical Applications
Print Queue Management
class PrintJob:
def __init__(self, document_name: str, pages: int, priority: str = "normal"):
self.document_name = document_name
self.pages = pages
self.priority = priority
self.timestamp = time.time() if 'time' in globals() else 0
def __str__(self):
return f"PrintJob({self.document_name}, {self.pages} pages, {self.priority})"
class PrintQueue:
def __init__(self):
self.normal_queue = Queue()
self.high_priority_queue = Queue()
self.current_job = None
def add_job(self, job: PrintJob):
"""Add a print job to the appropriate queue."""
if job.priority == "high":
self.high_priority_queue.enqueue(job)
print(f"Added high priority job: {job.document_name}")
else:
self.normal_queue.enqueue(job)
print(f"Added normal job: {job.document_name}")
def process_next_job(self):
"""Process the next print job (high priority first)."""
if not self.high_priority_queue.is_empty():
job = self.high_priority_queue.dequeue()
elif not self.normal_queue.is_empty():
job = self.normal_queue.dequeue()
else:
print("No jobs in queue")
return None
self.current_job = job
print(f"Processing: {job}")
return job
def get_queue_status(self):
"""Get current queue status."""
total_jobs = len(self.normal_queue) + len(self.high_priority_queue)
return {
"total_jobs": total_jobs,
"high_priority": len(self.high_priority_queue),
"normal_priority": len(self.normal_queue),
"current_job": str(self.current_job) if self.current_job else None
}
# Usage
printer = PrintQueue()
printer.add_job(PrintJob("report.pdf", 10))
printer.add_job(PrintJob("urgent.pdf", 2, "high"))
printer.add_job(PrintJob("memo.pdf", 1))
print(printer.get_queue_status())
printer.process_next_job() # Should process urgent.pdf first
printer.process_next_job() # Then report.pdf
Web Server Request Queue
class HttpRequest:
def __init__(self, method: str, url: str, client_ip: str):
self.method = method
self.url = url
self.client_ip = client_ip
self.timestamp = time.time() if 'time' in globals() else 0
def __str__(self):
return f"{self.method} {self.url} from {self.client_ip}"
class WebServer:
def __init__(self, max_concurrent_requests: int = 5):
self.request_queue = Queue()
self.processing_requests = []
self.max_concurrent = max_concurrent_requests
self.completed_requests = 0
def receive_request(self, request: HttpRequest):
"""Receive and queue a new request."""
self.request_queue.enqueue(request)
print(f"Queued: {request}")
def process_requests(self):
"""Process requests from the queue."""
# Start new requests if we have capacity
while (len(self.processing_requests) < self.max_concurrent and
not self.request_queue.is_empty()):
request = self.request_queue.dequeue()
self.processing_requests.append(request)
print(f"Processing: {request}")
# Simulate completing some requests
if self.processing_requests:
completed = self.processing_requests.pop(0)
self.completed_requests += 1
print(f"Completed: {completed}")
def get_server_status(self):
"""Get current server status."""
return {
"queued_requests": len(self.request_queue),
"processing_requests": len(self.processing_requests),
"completed_requests": self.completed_requests,
"next_in_queue": str(self.request_queue.front()) if not self.request_queue.is_empty() else None
}
# Usage
server = WebServer(max_concurrent_requests=2)
# Simulate incoming requests
requests = [
HttpRequest("GET", "/index.html", "192.168.1.1"),
HttpRequest("POST", "/api/data", "192.168.1.2"),
HttpRequest("GET", "/about.html", "192.168.1.3"),
HttpRequest("GET", "/contact.html", "192.168.1.4"),
]
for req in requests:
server.receive_request(req)
# Process requests
for _ in range(6): # Simulate several processing cycles
server.process_requests()
print(f"Status: {server.get_server_status()}")
print("---")
Cache with LRU Eviction
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = {} # key -> value
self.access_order = Queue() # Track access order for LRU
def get(self, key):
"""Get value by key, updating access order."""
if key in self.cache:
# Remove from queue and re-add to mark as recently used
temp_queue = Queue()
while not self.access_order.is_empty():
item = self.access_order.dequeue()
if item != key:
temp_queue.enqueue(item)
# Restore queue and add key as most recent
while not temp_queue.is_empty():
self.access_order.enqueue(temp_queue.dequeue())
self.access_order.enqueue(key)
return self.cache[key]
return None
def put(self, key, value):
"""Put key-value pair, evicting LRU if needed."""
if key in self.cache:
# Update existing key
self.cache[key] = value
self.get(key) # Update access order
else:
# Add new key
if len(self.cache) >= self.capacity:
# Evict least recently used
lru_key = self.access_order.dequeue()
del self.cache[lru_key]
print(f"Evicted LRU key: {lru_key}")
self.cache[key] = value
self.access_order.enqueue(key)
print(f"Added: {key} = {value}")
def show_cache_state(self):
"""Show current cache state."""
print(f"Cache: {self.cache}")
print(f"Access order (LRU to MRU): {self.access_order.to_list()}")
# Usage
cache = LRUCache(capacity=3)
cache.put("A", 1)
cache.put("B", 2)
cache.put("C", 3)
cache.show_cache_state()
print(f"Get A: {cache.get('A')}") # A becomes most recent
cache.show_cache_state()
cache.put("D", 4) # Should evict B (least recently used)
cache.show_cache_state()
Event Processing System
class Event:
def __init__(self, event_type: str, data: dict, priority: int = 0):
self.event_type = event_type
self.data = data
self.priority = priority
self.timestamp = time.time() if 'time' in globals() else 0
def __str__(self):
return f"Event({self.event_type}, priority={self.priority})"
class EventProcessor:
def __init__(self):
self.event_queue = Queue()
self.handlers = {}
self.processed_count = 0
def register_handler(self, event_type: str, handler_func):
"""Register a handler function for an event type."""
self.handlers[event_type] = handler_func
def emit_event(self, event: Event):
"""Add an event to the processing queue."""
self.event_queue.enqueue(event)
print(f"Emitted: {event}")
def process_events(self, max_events: int = None):
"""Process events from the queue."""
processed = 0
while not self.event_queue.is_empty():
if max_events and processed >= max_events:
break
event = self.event_queue.dequeue()
# Find and execute handler
if event.event_type in self.handlers:
try:
self.handlers[event.event_type](event)
print(f"Processed: {event}")
self.processed_count += 1
processed += 1
except Exception as e:
print(f"Error processing {event}: {e}")
else:
print(f"No handler for event type: {event.event_type}")
return processed
def get_queue_info(self):
"""Get information about the event queue."""
return {
"pending_events": len(self.event_queue),
"total_processed": self.processed_count,
"next_event": str(self.event_queue.front()) if not self.event_queue.is_empty() else None
}
# Usage
processor = EventProcessor()
# Register event handlers
def handle_user_login(event):
user = event.data.get('username')
print(f" User {user} logged in")
def handle_file_upload(event):
filename = event.data.get('filename')
size = event.data.get('size')
print(f" File {filename} uploaded ({size} bytes)")
def handle_error(event):
error_msg = event.data.get('message')
print(f" Error occurred: {error_msg}")
processor.register_handler("user_login", handle_user_login)
processor.register_handler("file_upload", handle_file_upload)
processor.register_handler("error", handle_error)
# Emit events
events = [
Event("user_login", {"username": "alice"}),
Event("file_upload", {"filename": "document.pdf", "size": 1024}),
Event("user_login", {"username": "bob"}),
Event("error", {"message": "Database connection failed"}),
Event("file_upload", {"filename": "image.jpg", "size": 2048}),
]
for event in events:
processor.emit_event(event)
# Process all events
print("\nProcessing events:")
processor.process_events()
print(f"\nFinal status: {processor.get_queue_info()}")
Use Cases
When to Use Queues
Good for:
- Task scheduling and job processing
- Breadth-first search algorithms
- Buffer for data streams
- Print job management
- Process scheduling
- Event handling systems
- Producer-consumer patterns
- Request handling in web servers
Examples:
# Task processing
task_queue = Queue()
task_queue.enqueue("process_data")
task_queue.enqueue("send_email")
task_queue.enqueue("backup_files")
# Buffer for streaming data
data_buffer = Queue()
data_buffer.enqueue(data_chunk_1)
data_buffer.enqueue(data_chunk_2)
# BFS traversal
bfs_queue = Queue()
bfs_queue.enqueue(root_node)
# Request handling
request_queue = Queue()
request_queue.enqueue(http_request)
When NOT to Use Queues
Avoid for:
- Random access to elements (use arrays/lists)
- LIFO processing (use stacks)
- Priority-based processing (use priority queues)
- Frequent middle insertions/deletions
Better alternatives:
# For random access, use list
random_access = [1, 2, 3, 4, 5]
print(random_access[2]) # Direct access to index 2
# For LIFO, use stack
from algo.data_structs.stacks_queues.stack import Stack
lifo_stack = Stack()
lifo_stack.push(1)
lifo_stack.pop() # LIFO behavior
# For priority-based processing, use priority queue
from algo.data_structs.trees.priority_queue import PriorityQueue
priority_queue = PriorityQueue()
priority_queue.put("urgent_task", 1)
priority_queue.put("normal_task", 5)
Performance Characteristics
Time Complexity Analysis
- Enqueue/Dequeue operations: O(1) - constant time
- Front/Rear operations: O(1) - constant time
- Search operations: O(n) - linear time
- Memory allocation: O(1) per element (linked list)
- Space overhead: Minimal (only node pointers)
Memory Efficiency
# Queue uses singly linked list internally
# Memory per element: data + one pointer
# No pre-allocation of fixed arrays
# Memory grows/shrinks dynamically
queue = Queue()
print(f"Empty queue memory efficient: {queue.is_empty()}")
# Memory usage scales linearly with elements
for i in range(1000):
queue.enqueue(i)
# Only allocates memory for actual elements
Comparison with Other Data Structures
| Operation | Queue | List | Deque | Stack |
|---|---|---|---|---|
| Add Front | N/A | O(n) | O(1) | O(1) |
| Add Rear | O(1) | O(1) | O(1) | N/A |
| Remove Front | O(1) | O(n) | O(1) | N/A |
| Remove Rear | N/A | O(1) | O(1) | O(1) |
| Random Access | O(n) | O(1) | O(n) | O(n) |
| Memory Overhead | Low | Medium | Low | Low |
| Use Case | FIFO | Random Access | Both Ends | LIFO |
API Reference
Queue Implementation
A queue is a First-In-First-Out (FIFO) data structure where elements are added at the rear (enqueue) and removed from the front (dequeue). It follows the principle that the first element added is the first one to be removed.
Key Features:
- FIFO (First In, First Out) ordering
- Enqueue operation adds element to rear
- Dequeue operation removes element from front
- Front operation views front element without removing it
- Dynamic size allocation
Common Use Cases:
- Task scheduling and job queues
- Breadth-first search (BFS) algorithms
- Buffer for data streams
- Print job management
- Process scheduling in operating systems
Time Complexities:
- Enqueue: O(1)
- Dequeue: O(1)
- Front: O(1)
- Size: O(1)
- Search: O(n)
Space Complexity: O(n)
Queue()
Bases: Generic[T]
A queue implementation using a singly linked list as the underlying data structure.
This implementation provides efficient O(1) enqueue and dequeue operations by maintaining references to both head and tail of the linked list.
Initialize an empty queue.
__contains__(value)
Check if a value exists in the queue.
__iter__()
Return an iterator over the queue elements.
Note: Iteration goes from front to rear (oldest to newest).
__len__()
Return the number of elements in the queue.
__repr__()
Return detailed string representation for debugging.
__str__()
Return string representation of the queue.
clear()
Remove all elements from the queue.
Time Complexity: O(1)
copy()
Create a shallow copy of the queue.
Time Complexity: O(n)
Returns:
| Type | Description |
|---|---|
Queue[T]
|
A new Queue with the same elements |
count(item)
Count the number of occurrences of an item in the queue.
Time Complexity: O(n)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item
|
T
|
Item to count |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of occurrences |
dequeue()
Remove and return the front element from the queue.
Time Complexity: O(1)
Returns:
| Type | Description |
|---|---|
T
|
The front element of the queue |
Raises:
| Type | Description |
|---|---|
IndexError
|
If the queue is empty |
enqueue(item)
Add an element to the rear of the queue.
Time Complexity: O(1)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item
|
T
|
Element to add to the queue |
required |
extend(iterable)
Enqueue all elements from an iterable onto the queue.
Time Complexity: O(k) where k is the number of elements
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
iterable
|
Any
|
Iterable containing elements to enqueue |
required |
Note
Elements are enqueued in order, maintaining FIFO behavior.
front()
Return the front element without removing it.
Time Complexity: O(1)
Returns:
| Type | Description |
|---|---|
T
|
The front element of the queue |
Raises:
| Type | Description |
|---|---|
IndexError
|
If the queue is empty |
is_empty()
Check if the queue is empty.
Time Complexity: O(1)
Returns:
| Type | Description |
|---|---|
bool
|
True if the queue is empty, False otherwise |
rear()
Return the rear element without removing it.
Time Complexity: O(1)
Returns:
| Type | Description |
|---|---|
T
|
The rear element of the queue |
Raises:
| Type | Description |
|---|---|
IndexError
|
If the queue is empty |
reverse()
Reverse the queue in place.
Time Complexity: O(n)
Note
After reversal, the front element becomes the rear element.
search(item)
Search for an item in the queue and return its position from the front.
Time Complexity: O(n)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item
|
T
|
Item to search for |
required |
Returns:
| Type | Description |
|---|---|
int
|
Position from front (0-based), or -1 if not found |
Note
Front element has position 0, second element has position 1, etc.
size()
Get the number of elements in the queue.
Time Complexity: O(1)
Returns:
| Type | Description |
|---|---|
int
|
The number of elements in the queue |
to_list()
Convert the queue to a Python list.
Time Complexity: O(n)
Returns:
| Type | Description |
|---|---|
list[T]
|
A Python list with elements from front to rear |