Queue implementation in Python
What is queue
Like stack, queue is also a linear data structure in which the items are stored in a First-In-First-Out(FIFO)manner.
The queue may include the following key functions.
- enqueue() - add an item to the end of the queue
- dequeue() - remove the front item
- size() - return the number of items in queue
- peek() - return the front item
- is_empty() - check if the queue is empty
How to implement
There are various ways to implement a queue in Python. In this post, we will learn how to implement it with the following ways.
- list
- collections.deque
- queue.Queue
- linked list
using list
In Python, list is like dynamic array. The items in list are stored contiguously in memory. Thus, the random access to list is as fast as array. However, inserting/deleting item in front of the queue is slow because it requires shifting other items with time complexity O(n).
st = []
st.append(1)
st.append(2)
st.append(3)
print("stack size: {}".format(len(st)))
print(st.pop(0))
print(st.pop(0))
print(st.pop(0))
print("stack size: {}".format(len(st)))
using collections.deque
deque is pronounced “deck” and stands for “double-ended queue”. It is built upon a doubly linked list which allows insert/remove nodes from both ends with constant time O(1). Deque is the prefered method to implement a queue in Python. Note that deque is not thread-safe.
from collections import deque
st = deque()
st.append(1)
st.append(2)
st.append(3)
print("stack size: {}".format(len(st)))
print(st.popleft())
print(st.popleft())
print(st.popleft())
print("stack size: {}".format(len(st)))
using queue.Queue
If you need multi-threading, you can use queue.Queue module. However, it comes at a performance cost to achieve the thread-safety.
from queue import Queue
st = Queue()
st.put(1)
st.put(2)
st.put(3)
print("stack size: {}".format(st.qsize()))
print(st.get())
print(st.get())
print(st.get())
print("stack size: {}".format(st.qsize()))
using linked list
You also can implement your own queue with the linked list data structure.
class Node:
def __init__(self, val):
self.val = val
self.next = None
class MyQueue:
def __init__(self):
self.front = self.rear = None
self.size = 0
def get_size(self):
return self.size
def is_empty(self):
return self.size == 0
def enqueue(self, val):
n = Node(val)
if self.rear == None:
self.front = n
self.rear = n
else:
self.rear.next = n
self.rear = n
self.size += 1
def dequeue(self):
if self.is_empty():
raise Exception("empty stack")
val = self.front.val
self.front = self.front.next
self.size -= 1
return val
def __str__(self):
curr = self.front
st_str = ""
while curr:
st_str += str(curr.val) + "->"
curr = curr.next
return st_str[:-2]
qu = MyQueue()
qu.enqueue(1)
qu.enqueue(2)
qu.enqueue(3)
print("queue: {}".format(qu))
print("queue size: {}".format(qu.size))
print(qu.dequeue())
print(qu.dequeue())
print(qu.dequeue())
print("queue size: {}".format(qu.size))