Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python Program to Implement Queue Data Structure using Linked List
A queue is a linear data structure that follows the First In First Out (FIFO) principle. When implementing a queue using a linked list, we need methods to add elements at the rear (enqueue) and remove elements from the front (dequeue).
Queue Implementation Structure
Our queue implementation consists of two classes ?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
Enqueue Operation
The enqueue operation adds an element to the rear of the queue ?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
def enqueue(self, data):
new_node = Node(data)
if self.rear is None:
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
print(f"Enqueued: {data}")
def display(self):
if self.front is None:
print("Queue is empty")
return
current = self.front
elements = []
while current:
elements.append(str(current.data))
current = current.next
print("Queue:", " -> ".join(elements))
# Example usage
queue = Queue()
queue.enqueue(10)
queue.enqueue(20)
queue.enqueue(30)
queue.display()
Enqueued: 10 Enqueued: 20 Enqueued: 30 Queue: 10 -> 20 -> 30
Dequeue Operation
The dequeue operation removes and returns the element from the front of the queue ?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
def enqueue(self, data):
new_node = Node(data)
if self.rear is None:
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
def dequeue(self):
if self.front is None:
print("Queue is empty")
return None
removed_data = self.front.data
self.front = self.front.next
# If queue becomes empty, update rear to None
if self.front is None:
self.rear = None
return removed_data
def display(self):
if self.front is None:
print("Queue is empty")
return
current = self.front
elements = []
while current:
elements.append(str(current.data))
current = current.next
print("Queue:", " -> ".join(elements))
# Example usage
queue = Queue()
queue.enqueue(45)
queue.enqueue(12)
queue.enqueue(78)
queue.display()
print(f"Dequeued: {queue.dequeue()}")
queue.display()
print(f"Dequeued: {queue.dequeue()}")
queue.display()
Queue: 45 -> 12 -> 78 Dequeued: 45 Queue: 12 -> 78 Dequeued: 12 Queue: 78
Complete Queue Implementation
Here's the complete queue implementation with additional utility methods ?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
self.size = 0
def enqueue(self, data):
new_node = Node(data)
if self.rear is None:
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
self.size += 1
def dequeue(self):
if self.front is None:
return None
removed_data = self.front.data
self.front = self.front.next
if self.front is None:
self.rear = None
self.size -= 1
return removed_data
def is_empty(self):
return self.front is None
def get_size(self):
return self.size
def peek(self):
return self.front.data if self.front else None
# Demonstration
queue = Queue()
# Enqueue elements
for value in [10, 20, 30, 40]:
queue.enqueue(value)
print(f"Enqueued: {value}, Size: {queue.get_size()}")
# Dequeue elements
while not queue.is_empty():
front_element = queue.peek()
dequeued = queue.dequeue()
print(f"Dequeued: {dequeued}, Remaining size: {queue.get_size()}")
Enqueued: 10, Size: 1 Enqueued: 20, Size: 2 Enqueued: 30, Size: 3 Enqueued: 40, Size: 4 Dequeued: 10, Remaining size: 3 Dequeued: 20, Remaining size: 2 Dequeued: 30, Remaining size: 1 Dequeued: 40, Remaining size: 0
Key Features
| Operation | Time Complexity | Description |
|---|---|---|
| Enqueue | O(1) | Add element to rear |
| Dequeue | O(1) | Remove element from front |
| Peek | O(1) | View front element |
| Is Empty | O(1) | Check if queue is empty |
Conclusion
Implementing a queue using linked lists provides dynamic memory allocation and efficient O(1) enqueue and dequeue operations. This approach is memory-efficient as it only uses space for the elements currently in the queue.
