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.

Updated on: 2026-03-25T18:37:56+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements