CircularArray Implementation of Queue
A Circular Queue is a way of implementing a normal queue where the last element of the queue is connected to the first element of the queue forming a circle.
The operations are performed based on the FIFO (First In First Out) principle. It is also called ‘Ring Buffer’. In a normal Queue, we can insert elements until the queue becomes full. However once the queue becomes full, we can not insert the next element even if there is a space in front of the queue.
Table of Content
Operations on Queue
- getFront: Get the front item from the queue.
- getRear: Get the last item from the queue.
- enqueue(value): To insert an element into the circular queue. In a circular queue, the new element is always inserted at the rear position.
- dequeue(): To delete an element from the circular queue. In a circular queue, the element is always deleted from the front position.
Simple Array Implementation of Queue
One simple way to implement a queue is by using a simple queue, where elements are added at the rear and removed from the front but it can lead to inefficiency as we need move all elements after front. In this implementation, enqueue() is O(1), but dequeue is O(n).
To read more, Refer Array implementation of queue – Simple
We use a circular array instead of a simple array because a circular array allows both enqueue() and dequeue() in O(1). We move front and rear pointers in circular fashion.
Implement Queue using Circular Array
- Initialize an array of size n, where n is the maximum number of elements that the queue can hold.
- Initialize three variables (size, capacity, and front.)
- Enqueue: To enqueue an element x into the queue, do the following:
- Check if size == capacity (queue is full), display “Queue is full”.
- If not full: calculate rear = (front + size) % capacity and Insert value at the rear index. Increment size by 1.
- Dequeue: To dequeue an element from the queue, do the following:
- Check if size == 0 (queue is empty), display “Queue is empty”.
- If not empty: retrieve the element at the front index and move front = (front + 1) % capacity. Also, decrement size by 1 and return the removed element.
Illustration of Circular Queue:












Below is the implementation of above approach:
// C++ program for insertion and
// deletion in Circular Queue
#include <iostream>
using namespace std;
class Queue {
private:
int *arr;
int front, size;
int capacity;
public:
// Constructor to initialize the queue
Queue(int c) {
arr = new int[c];
capacity = c;
size = 0;
front = 0;
}
// Get the front element
int getFront() {
// Queue is empty
if (size == 0)
return -1;
return arr[front];
}
// Get the rear element
int getRear() {
// Queue is empty
if (size == 0)
return -1;
int rear = (front + size - 1) % capacity;
return arr[rear];
}
// Insert an element at the rear
void enqueue(int x) {
// Queue is full
if (size == capacity)
return;
int rear = (front + size) % capacity;
arr[rear] = x;
size++;
}
// Remove an element from the front
int dequeue() {
// Queue is empty
if (size == 0)
return -1;
int res = arr[front];
front = (front + 1) % capacity;
size--;
return res;
}
};
int main() {
Queue q(4);
q.enqueue(10);
cout << q.getFront() << " " << q.getRear() << endl;
q.enqueue(20);
cout << q.getFront() << " " << q.getRear() << endl;
q.enqueue(30);
cout << q.getFront() << " " << q.getRear() << endl;
q.enqueue(40);
cout << q.getFront() << " " << q.getRear() << endl;
q.dequeue();
cout << q.getFront() << " " << q.getRear() << endl;
q.dequeue();
cout << q.getFront() << " " << q.getRear() << endl;
q.enqueue(50);
cout << q.getFront() << " " << q.getRear() << endl;
return 0;
}
// Java program for insertion and deletion in Circular Queue
class Queue {
private int[] arr;
private int front, size;
private int capacity;
// Constructor to initialize the queue
public Queue(int c) {
arr = new int[c];
capacity = c;
size = 0;
front = 0;
}
// Get the front element
public int getFront() {
// Queue is empty
if (size == 0)
return -1;
return arr[front];
}
// Get the rear element
public int getRear() {
// Queue is empty
if (size == 0)
return -1;
int rear = (front + size - 1) % capacity;
return arr[rear];
}
// Insert an element at the rear
public void enqueue(int x) {
// Queue is full
if (size == capacity)
return;
int rear = (front + size) % capacity;
arr[rear] = x;
size++;
}
// Remove an element from the front
public int dequeue() {
// Queue is empty
if (size == 0)
return -1;
int res = arr[front];
front = (front + 1) % capacity;
size--;
return res;
}
}
public class Main {
public static void main(String[] args) {
Queue q = new Queue(4);
q.enqueue(10);
System.out.println(q.getFront() + " " + q.getRear());
q.enqueue(20);
System.out.println(q.getFront() + " " + q.getRear());
q.enqueue(30);
System.out.println(q.getFront() + " " + q.getRear());
q.enqueue(40);
System.out.println(q.getFront() + " " + q.getRear());
q.dequeue();
System.out.println(q.getFront() + " " + q.getRear());
q.dequeue();
System.out.println(q.getFront() + " " + q.getRear());
q.enqueue(50);
System.out.println(q.getFront() + " " + q.getRear());
}
}
# Python program for insertion and deletion in Circular Queue
class Queue:
def __init__(self, c):
self.arr = [0] * c
self.capacity = c
self.size = 0
self.front = 0
# Get the front element
def getFront(self):
# Queue is empty
if self.size == 0:
return -1
return self.arr[self.front]
# Get the rear element
def getRear(self):
# Queue is empty
if self.size == 0:
return -1
rear = (self.front + self.size - 1) % self.capacity
return self.arr[rear]
# Insert an element at the rear
def enqueue(self, x):
# Queue is full
if self.size == self.capacity:
return
rear = (self.front + self.size) % self.capacity
self.arr[rear] = x
self.size += 1
# Remove an element from the front
def dequeue(self):
# Queue is empty
if self.size == 0:
return -1
res = self.arr[self.front]
self.front = (self.front + 1) % self.capacity
self.size -= 1
return res
if __name__ == '__main__':
q = Queue(4)
q.enqueue(10)
print(q.getFront(), q.getRear())
q.enqueue(20)
print(q.getFront(), q.getRear())
q.enqueue(30)
print(q.getFront(), q.getRear())
q.enqueue(40)
print(q.getFront(), q.getRear())
q.dequeue()
print(q.getFront(), q.getRear())
q.dequeue()
print(q.getFront(), q.getRear())
q.enqueue(50)
print(q.getFront(), q.getRear())
// C# program for insertion and deletion in Circular Queue
using System;
class Queue {
private int[] arr;
private int front, size;
private int capacity;
// Constructor to initialize the queue
public Queue(int c) {
arr = new int[c];
capacity = c;
size = 0;
front = 0;
}
// Get the front element
public int GetFront() {
// Queue is empty
if (size == 0)
return -1;
return arr[front];
}
// Get the rear element
public int GetRear() {
// Queue is empty
if (size == 0)
return -1;
int rear = (front + size - 1) % capacity;
return arr[rear];
}
// Insert an element at the rear
public void Enqueue(int x) {
// Queue is full
if (size == capacity)
return;
int rear = (front + size) % capacity;
arr[rear] = x;
size++;
}
// Remove an element from the front
public int Dequeue() {
// Queue is empty
if (size == 0)
return -1;
int res = arr[front];
front = (front + 1) % capacity;
size--;
return res;
}
}
class Program {
static void Main() {
Queue q = new Queue(4);
q.Enqueue(10);
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Enqueue(20);
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Enqueue(30);
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Enqueue(40);
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Dequeue();
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Dequeue();
Console.WriteLine(q.GetFront() + " " + q.GetRear());
q.Enqueue(50);
Console.WriteLine(q.GetFront() + " " + q.GetRear());
}
}
// JavaScript program for insertion and deletion in Circular Queue
class Queue {
constructor(c) {
this.arr = new Array(c);
this.capacity = c;
this.size = 0;
this.front = 0;
}
// Get the front element
getFront() {
// Queue is empty
if (this.size === 0)
return -1;
return this.arr[this.front];
}
// Get the rear element
getRear() {
// Queue is empty
if (this.size === 0)
return -1;
const rear = (this.front + this.size - 1) % this.capacity;
return this.arr[rear];
}
// Insert an element at the rear
enqueue(x) {
// Queue is full
if (this.size === this.capacity)
return;
const rear = (this.front + this.size) % this.capacity;
this.arr[rear] = x;
this.size++;
}
// Remove an element from the front
dequeue() {
// Queue is empty
if (this.size === 0)
return -1;
const res = this.arr[this.front];
this.front = (this.front + 1) % this.capacity;
this.size--;
return res;
}
}
const q = new Queue(4);
q.enqueue(10);
console.log(q.getFront() + " " + q.getRear());
q.enqueue(20);
console.log(q.getFront() + " " + q.getRear());
q.enqueue(30);
console.log(q.getFront() + " " + q.getRear());
q.enqueue(40);
console.log(q.getFront() + " " + q.getRear());
q.dequeue();
console.log(q.getFront() + " " + q.getRear());
q.dequeue();
console.log(q.getFront() + " " + q.getRear());
q.enqueue(50);
console.log(q.getFront() + " " + q.getRear());
Output
10 10 10 20 10 30 10 40 20 40 30 40 30 50
Complexity Analysis of Circular Queue Operations
Time Complexity:
Operation | Time Complexity |
---|---|
enqueue(x) | O(1) |
dequeue() | O(1) |
getFront() | O(1) |
getRear() | O(1) |
Auxiliary Space: O(size), where size is the number of elements in the circular queue.
Related article: