In this section, we will provide a series of practical exercises to reinforce your understanding of queues. Each exercise will include a problem statement, followed by a detailed solution. We will also highlight common mistakes and provide additional tips to help you master the concepts.
Exercise 1: Implementing a Queue
Problem Statement
Implement a queue using a list in Python. Your queue should support the following operations:
enqueue(item): Add an item to the end of the queue.dequeue(): Remove and return the item from the front of the queue. If the queue is empty, returnNone.is_empty(): ReturnTrueif the queue is empty, otherwise returnFalse.size(): Return the number of items in the queue.
Solution
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
if self.is_empty():
return None
return self.items.pop(0)
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
# Example usage:
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.dequeue()) # Output: 1
print(queue.size()) # Output: 2
print(queue.is_empty()) # Output: FalseExplanation
- enqueue(item): Adds an item to the end of the list using
append(). - dequeue(): Removes the first item from the list using
pop(0). If the queue is empty, it returnsNone. - is_empty(): Checks if the list is empty by comparing its length to zero.
- size(): Returns the length of the list.
Common Mistakes
- Forgetting to check if the queue is empty before calling
dequeue(). - Using
pop()without an index, which removes the last item instead of the first.
Exercise 2: Circular Queue Implementation
Problem Statement
Implement a circular queue using a fixed-size list (array). Your queue should support the following operations:
enqueue(item): Add an item to the end of the queue. If the queue is full, returnFalse.dequeue(): Remove and return the item from the front of the queue. If the queue is empty, returnNone.is_empty(): ReturnTrueif the queue is empty, otherwise returnFalse.is_full(): ReturnTrueif the queue is full, otherwise returnFalse.size(): Return the number of items in the queue.
Solution
class CircularQueue:
def __init__(self, capacity):
self.capacity = capacity
self.queue = [None] * capacity
self.front = self.rear = -1
def enqueue(self, item):
if self.is_full():
return False
if self.front == -1:
self.front = 0
self.rear = (self.rear + 1) % self.capacity
self.queue[self.rear] = item
return True
def dequeue(self):
if self.is_empty():
return None
item = self.queue[self.front]
if self.front == self.rear:
self.front = self.rear = -1
else:
self.front = (self.front + 1) % self.capacity
return item
def is_empty(self):
return self.front == -1
def is_full(self):
return (self.rear + 1) % self.capacity == self.front
def size(self):
if self.is_empty():
return 0
if self.rear >= self.front:
return self.rear - self.front + 1
return self.capacity - self.front + self.rear + 1
# Example usage:
cq = CircularQueue(3)
print(cq.enqueue(1)) # Output: True
print(cq.enqueue(2)) # Output: True
print(cq.enqueue(3)) # Output: True
print(cq.enqueue(4)) # Output: False (Queue is full)
print(cq.dequeue()) # Output: 1
print(cq.size()) # Output: 2
print(cq.is_empty()) # Output: False
print(cq.is_full()) # Output: FalseExplanation
- enqueue(item): Adds an item to the queue. If the queue is full, it returns
False. Otherwise, it updates therearindex and inserts the item. - dequeue(): Removes the item from the front of the queue. If the queue is empty, it returns
None. Otherwise, it updates thefrontindex. - is_empty(): Checks if the queue is empty by comparing
frontto-1. - is_full(): Checks if the queue is full by comparing the next position of
reartofront. - size(): Calculates the number of items in the queue based on the positions of
frontandrear.
Common Mistakes
- Not handling the wrap-around condition correctly in
enqueue()anddequeue(). - Forgetting to reset
frontandrearto-1when the queue becomes empty after adequeue()operation.
Exercise 3: Priority Queue Implementation
Problem Statement
Implement a priority queue using a list of tuples in Python. Each tuple should contain an item and its priority. Your priority queue should support the following operations:
enqueue(item, priority): Add an item with a given priority to the queue.dequeue(): Remove and return the item with the highest priority. If the queue is empty, returnNone.is_empty(): ReturnTrueif the queue is empty, otherwise returnFalse.size(): Return the number of items in the queue.
Solution
class PriorityQueue:
def __init__(self):
self.queue = []
def enqueue(self, item, priority):
self.queue.append((item, priority))
self.queue.sort(key=lambda x: x[1], reverse=True)
def dequeue(self):
if self.is_empty():
return None
return self.queue.pop(0)[0]
def is_empty(self):
return len(self.queue) == 0
def size(self):
return len(self.queue)
# Example usage:
pq = PriorityQueue()
pq.enqueue('task1', 1)
pq.enqueue('task2', 3)
pq.enqueue('task3', 2)
print(pq.dequeue()) # Output: 'task2'
print(pq.size()) # Output: 2
print(pq.is_empty()) # Output: FalseExplanation
- enqueue(item, priority): Adds a tuple
(item, priority)to the queue and sorts the queue based on priority in descending order. - dequeue(): Removes and returns the item with the highest priority (first item in the sorted list). If the queue is empty, it returns
None. - is_empty(): Checks if the queue is empty by comparing its length to zero.
- size(): Returns the length of the queue.
Common Mistakes
- Forgetting to sort the queue after adding a new item.
- Using the wrong sorting order (ascending instead of descending).
Conclusion
In this section, we have covered various exercises to help you understand and implement different types of queues, including simple queues, circular queues, and priority queues. By practicing these exercises, you should have a solid understanding of how queues work and how to implement them in Python.
Next, we will move on to the next module, which focuses on trees, another fundamental data structure in programming.
Data Structures Course
Module 1: Introduction to Data Structures
Module 2: Lists
Module 3: Stacks
- Introduction to Stacks
- Basic Operations with Stacks
- Stack Implementation
- Applications of Stacks
- Exercises with Stacks
Module 4: Queues
- Introduction to Queues
- Basic Operations with Queues
- Circular Queues
- Priority Queues
- Exercises with Queues
Module 5: Trees
Module 6: Graphs
- Introduction to Graphs
- Graph Representation
- Graph Search Algorithms
- Shortest Path Algorithms
- Applications of Graphs
- Exercises with Graphs
