Circular Array Implementation of Queue
Last Updated :
28 Mar, 2025
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.
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++
// 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
// 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
# 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#
// 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
// 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());
Output10 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:
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read