A circular queue is a queue in which all elements are connected to form a circular. A circular queue can be implemented with an array or a linked list. In array implementation, the front and rear wrap-around (modulo operation) to the beginning of the array. In this post, circular queue implementation uses using an array.
Table of Content
Map of queue implementations
Part 1 – Queue implementation using a linked list
Part 2 – Circular queue implementation using an array
Part 3 – Circular queue (Circular linked list)
Part 4 – Deque (Doubly linked list)
Enqueue in circular queue implementation
In the class, declare an array. In Java, if you use an array, not ArrayList, you have to specify the maxSize. If the array reaches the maxSize, you cannot add more elements. frontIndex and rearIndex are the index of the front element and rear element. When the queue is empty, they are -1. length is to keep track of the number of elements in the queue.
To enqueue is to add an element at the rear. rearIndex is increased by 1. If the rearIndex exceeds the maxSize, you use the modulo operation (or “mod”, “%”) to get the new rearIndex with the maxSize range.
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class CircularQueueArray<T> { private T[] array; private int maxSize; // Size of Circular Queue private int frontIndex, rearIndex; private int length = 0; //constructor, Time O(1), Space O(1) @SuppressWarnings("unchecked") public CircularQueueArray(int size) { maxSize = size; frontIndex = -1; rearIndex = -1; array = (T[])new Object[maxSize]; } //Add at the rear, Time O(1), Space O(1) public void enqueue(T value) { if (isFull()) { System.out.println("Queue is full, cannot enqueue "+ value); return; } if (frontIndex == -1) //empty frontIndex = 0; rearIndex = (rearIndex + 1) % maxSize; array[rearIndex] = value; length++; } // Check full, Time O(1), Space O(1) private boolean isFull() { return (rearIndex + 1) % maxSize == frontIndex; } |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class CircularQueueArray { //constructor, Time O(1), Space O(1) constructor(size) { this.maxSize = size; this.frontIndex = -1; this.rearIndex = -1; this.queueArray = []; this.length = 0; } //Add at the rear, Time O(1), Space O(1) enqueue(value) { if (this.isFull()) { console.log("Queue is full, cannot enqueue "+ value); return; } if (this.frontIndex == -1) this.frontIndex = 0; this.rearIndex = (this.rearIndex + 1) % this.maxSize; this.queueArray[this.rearIndex] = value; this.length++; } // Check if the queue is full, Time O(1), Space O(1) isFull() { return (this.rearIndex + 1) % this.maxSize == this.frontIndex; } |
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class CircularQueueArray: #constructor, Time O(1), Space O(1) def __init__(self, size): self.maxSize = size self.queueArray = [None] * size self.frontIndex = self.rearIndex = -1 self.length = 0 #Add at the rear, Time O(1), Space O(1) def enqueue(self, value): if self.is_full(): #full print("The circular queue is full, cannot enqueue " + str(value)) return if (self.frontIndex == -1): #empty self.frontIndex = 0 self.rearIndex = (self.rearIndex + 1) % self.maxSize self.queueArray[self.rearIndex] = value self.length += 1 #Check full, Time O(1), Space O(1) def is_full(self): return (self.rearIndex + 1) % self.maxSize == self.frontIndex |
Doodle
Dequeue in circular queue implementation
The dequeue operation is to remove the front node from the queue. First, you check whether the queue is empty. If it is empty, the method should return. You also check whether there is only one element in the queue. If it is, you should reset frontIndex and rearIndex to -1 after removing the last element.
To dequeue, you increase the frontIndex by 1. If frontIndex exceeds maxSize, you have to put the element back to index 0. You use the modulo operation (“mod”, “%”) to get the new frontIndex. Please note to dequeue elements, you only update frontIndex. The original value stays in the spot until it is replaced with the new value.
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //Remove from the front, Time O(1), Space O(1) public T dequeue() { if (isEmpty()) { System.out.println("Queue is empty"); return null; } T item = array[frontIndex]; if (frontIndex == rearIndex) { //last one, reset frontIndex = -1; rearIndex = -1; } else { frontIndex = (frontIndex + 1) % maxSize; } length--; return (item); } //Check empty, Time O(1), Space O(1) private boolean isEmpty() { return frontIndex == -1; } |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //Remove from the front, Time O(1), Space O(1) dequeue() { if (this.isEmpty()) { console.log("Queue is empty"); return null; } var item = this.queueArray[this.frontIndex]; if (this.frontIndex == this.rearIndex) { //one element left this.frontIndex = -1; this.rearIndex = -1; } else { this.frontIndex = (this.frontIndex + 1) % this.maxSize; } this.length--; return (item); } //Check if the queue is empty, Time O(1), Space O(1) isEmpty() { return this.frontIndex == -1; } |
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Remove from the front, Time O(1), Space O(1) def dequeue(self): if self.is_empty(): print("The circular queue is empty, cannot dequeue") return item = self.queueArray[self.frontIndex] if (self.frontIndex == self.rearIndex): #one item left self.frontIndex = -1 self.rearIndex = -1 else: self.frontIndex = (self.frontIndex + 1) % self.maxSize self.length -= 1 return item #Check empty, Time O(1), Space O(1) def is_empty(self): return self.frontIndex == -1 |
Doodle
Peek
Peek is to return the value at firstIndex. Please also should check whether the queue is empty. If it is not empty, return the value.
Java
1 2 3 4 5 6 7 8 | //Return front value, Time O(1), Space O(1) public T peek() { if (isEmpty()) { System.out.println("Queue is empty"); return null; } return array[frontIndex]; } |
Javascript
1 2 3 4 5 6 7 8 | //Return front value, Time O(1), Space O(1) peek() { if (this.isEmpty()) { console.log("Queue is empty"); return null; } return this.queueArray[this.frontIndex]; } |
Python
1 2 3 4 5 6 | #Return front value, Time O(1), Space O(1) def peek(self): if self.is_empty(): print("The circular queue is empty, cannot dequeue") return return self.queueArray[self.frontIndex] |
Print
Print is to print all elements in the circular queue. Starting from frontIndex, a for loop or while loop can be used to iterate through each slot till to rearIndex. The index i is increased by 1, then mod maxSize.
Java
1 2 3 4 5 6 7 8 9 10 11 | //Print all, Time O(n), Space O(1), n is number of items in queue public void print() { if (isEmpty()) { System.out.println("Queue is empty"); return; } int i; for (i = frontIndex; i != rearIndex; i = (i+1) % maxSize) System.out.print(array[i] + " "); System.out.println(array[i]); } |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 | //Print all, Time O(n), Space O(n), n is number of items in queue print() { if (this.isEmpty()) { console.log("Queue is empty"); return; } var str = ""; var i; for (i = this.frontIndex; i != this.rearIndex; i = (i+1) % this.maxSize) str += this.queueArray[i] + " "; str += this.queueArray[i]; console.log(str); } |
Python
1 2 3 4 5 6 7 8 9 10 | #Print all, Time O(n), Space O(1), n is number of items in queue def print(self): if self.is_empty(): print("The circular queue is empty") return i = self.frontIndex while i != self.rearIndex: print(str(self.queueArray[i]) , end = " ") i = (i + 1) % self.maxSize print(self.queueArray[i]) |
Free download
Download circular queue implementation in Java, JavaScript and Python
Data structures and Java collections
What is the wrap-around technique used in a circular queue?
The wrap-around is to use modulo operation to make sure frontIndex and rearIndex with the range of maxSize of the array. For example, to enqueue, the formula is rearIndex = (rearIndex + 1) % maxSize. To dequeue, it is frontIndex = (frontIndex + 1) % maxSize.