From 9717a3ba9d664dfd82a736bd53c761a1db626c19 Mon Sep 17 00:00:00 2001 From: sufiyan kazi Date: Mon, 30 Mar 2026 15:33:17 +0530 Subject: [PATCH] Refactor queue implementation using linked list with O(1) operations and improved readability Refactor LinkedQueue implementation for clarity and efficiency. Added size tracking and improved method names. --- data_structures/queues/linked_queue.py | 194 +++++++++---------------- 1 file changed, 71 insertions(+), 123 deletions(-) diff --git a/data_structures/queues/linked_queue.py b/data_structures/queues/linked_queue.py index 80f6d309af9a..372152aafee1 100644 --- a/data_structures/queues/linked_queue.py +++ b/data_structures/queues/linked_queue.py @@ -1,156 +1,104 @@ -"""A Queue using a linked list like structure""" +""" +Queue Implementation using Linked List (Optimized) -from __future__ import annotations +- Time Complexity: + enqueue → O(1) + dequeue → O(1) + is_empty → O(1) + size → O(1) + +Author: Sufiyan +""" -from collections.abc import Iterator -from typing import Any +from __future__ import annotations +from typing import Any, Iterator class Node: + """A node in the linked list.""" + def __init__(self, data: Any) -> None: - self.data: Any = data + self.data = data self.next: Node | None = None - def __str__(self) -> str: - return f"{self.data}" - class LinkedQueue: - """ - >>> queue = LinkedQueue() - >>> queue.is_empty() - True - >>> queue.put(5) - >>> queue.put(9) - >>> queue.put('python') - >>> queue.is_empty() - False - >>> queue.get() - 5 - >>> queue.put('algorithms') - >>> queue.get() - 9 - >>> queue.get() - 'python' - >>> queue.get() - 'algorithms' - >>> queue.is_empty() - True - >>> queue.get() - Traceback (most recent call last): - ... - IndexError: dequeue from empty queue - """ + """Efficient Queue implementation using a linked list (FIFO).""" def __init__(self) -> None: self.front: Node | None = None self.rear: Node | None = None - - def __iter__(self) -> Iterator[Any]: - node = self.front - while node: - yield node.data - node = node.next + self._size: int = 0 # 🔥 O(1) size tracking def __len__(self) -> int: - """ - >>> queue = LinkedQueue() - >>> for i in range(1, 6): - ... queue.put(i) - >>> len(queue) - 5 - >>> for i in range(1, 6): - ... assert len(queue) == 6 - i - ... _ = queue.get() - >>> len(queue) - 0 - """ - return len(tuple(iter(self))) + """Return number of elements in queue (O(1)).""" + return self._size + + def __iter__(self) -> Iterator[Any]: + """Iterate through elements.""" + current = self.front + while current: + yield current.data + current = current.next def __str__(self) -> str: - """ - >>> queue = LinkedQueue() - >>> for i in range(1, 4): - ... queue.put(i) - >>> queue.put("Python") - >>> queue.put(3.14) - >>> queue.put(True) - >>> str(queue) - '1 <- 2 <- 3 <- Python <- 3.14 <- True' - """ - return " <- ".join(str(item) for item in self) + """String representation.""" + return " <- ".join(map(str, self)) def is_empty(self) -> bool: - """ - >>> queue = LinkedQueue() - >>> queue.is_empty() - True - >>> for i in range(1, 6): - ... queue.put(i) - >>> queue.is_empty() - False - """ - return len(self) == 0 - - def put(self, item: Any) -> None: - """ - >>> queue = LinkedQueue() - >>> queue.get() - Traceback (most recent call last): - ... - IndexError: dequeue from empty queue - >>> for i in range(1, 6): - ... queue.put(i) - >>> str(queue) - '1 <- 2 <- 3 <- 4 <- 5' - """ - node = Node(item) - if self.is_empty(): - self.front = self.rear = node + """Check if queue is empty (O(1)).""" + return self.front is None + + # 🔥 Professional naming (industry standard) + def enqueue(self, item: Any) -> None: + """Add element to rear (O(1)).""" + new_node = Node(item) + + if self.rear is None: + self.front = self.rear = new_node else: - assert isinstance(self.rear, Node) - self.rear.next = node - self.rear = node - - def get(self) -> Any: - """ - >>> queue = LinkedQueue() - >>> queue.get() - Traceback (most recent call last): - ... - IndexError: dequeue from empty queue - >>> queue = LinkedQueue() - >>> for i in range(1, 6): - ... queue.put(i) - >>> for i in range(1, 6): - ... assert queue.get() == i - >>> len(queue) - 0 - """ + self.rear.next = new_node + self.rear = new_node + + self._size += 1 + + def dequeue(self) -> Any: + """Remove element from front (O(1)).""" if self.is_empty(): raise IndexError("dequeue from empty queue") - assert isinstance(self.front, Node) - node = self.front + + assert self.front is not None + temp = self.front self.front = self.front.next + if self.front is None: self.rear = None - return node.data + + self._size -= 1 + return temp.data + + def peek(self) -> Any: + """Return front element without removing.""" + if self.is_empty(): + raise IndexError("peek from empty queue") + + assert self.front is not None + return self.front.data def clear(self) -> None: - """ - >>> queue = LinkedQueue() - >>> for i in range(1, 6): - ... queue.put(i) - >>> queue.clear() - >>> len(queue) - 0 - >>> str(queue) - '' - """ + """Remove all elements.""" self.front = self.rear = None + self._size = 0 if __name__ == "__main__": - from doctest import testmod + q = LinkedQueue() + + q.enqueue(10) + q.enqueue(20) + q.enqueue(30) - testmod() + print("Queue:", q) + print("Front:", q.peek()) + print("Dequeued:", q.dequeue()) + print("Queue after dequeue:", q)