C++ Program to Implement Circular Queue
Last Updated :
24 May, 2024
In C++, Queues are a fundamental data structure in computer science which works on the principle of FIFO (First In, First Out). They can be implemented using both array and linked list. A circular queue is a type of queue in which the last element is connected to the first element, forming a circular structure. In this article, we'll learn about circular queue, how to implement it in C++, and analyze its complexity.
What is Circular Queue in C++?
In a circular queue is a queue where the last element of the queue is connected to the first element of the queue. As it is a queue, it follows the FIFO (First-In-First-Out) order of operation. It is also known as "Ring buffer" as the resulted data structure is logically circular.
Consider a scenario where you're simulating a printer queue. New documents are constantly being added to the queue, and as they are printed, they are removed. In a circular queue, if the queue becomes full and documents are printed, new documents can still be added at the beginning of the queue, as it is circular in nature.
Why we need Circular Queue in C++?
Circular queue concept is especially helpful when the queue is implemented using an array. In linear implementation, when the rear pointer reaches the end of the queue, we cannot insert new elements even if there are empty locations in the queue.
Circular queues address this limitation by connecting the front and rear ends, allowing the rear to go back to the start in when the rear reaches the end of the queue.
Concept Behind Circular Queue
There are two different concepts behind circular queue depending upon which data structure it is using in its implementation:
For Linked List Implementation, we can directly use the circular linked list where the last element of the list points to the head of the list.
For Array Implementation
For array implementation for circular queue, we use the mathematical concept of modular (or circular) increment. In this concept, a value that is being incremented will wrap around a particular threshold value. It can be achieved using the formula.
value = (value + 1) % threshold_value;
For Example, if value is 9, and threshold is 10. Incrementing the value by 1 will make it 10 and dividing it with 10 will yield the remainder 0.
Basic Operations on Circular Queue in C++
The basic operations of the circular queue are same as that of normal queue but the implementation is different. The following table list the basic operations in circular queue:
Operation
| Description
| Time Complexity
| Space Complexity
|
---|
Enqueue
| This function is used to insert an element into the circular queue.
| O(1)
| O(1)
|
---|
Dequeue
| This function is used to delete an element from the circular queue.
| O(1)
| O(1)
|
---|
Peek
| Returns the front element of the queue.
| O(1)
| O(1)
|
---|
IsFull
| Returns true is the queue is full otherwise returns false.
| O(1)
| O(1)
|
---|
IsEmpty
| Returns true is the queue is empty otherwise returns false. | O(1)
| O(1) |
---|
Representation of Circular Queue in C++
The circular queue in C++ can be represented as a class which contains the rear and front index pointers, array to store queue elements, and the member functions to provide the basic operations.
class Queue {
private:
int front, rear;
int arr[MAX_SIZE];
public
........
}
Implementation of isEmpty for Circular Queue
The queue is only empty when the front == rear pointer
Algorithm of isEmpty
if front is equal to rear
return true
else
return false
Implementation of isFull for Circular Queue
The queue will be full when the incremented rear pointer is equal to the front pointer.
Algorithm of isFull
if (rear + 1) % size is equal to front
return true;
else
return false;
Implementation of Enqueue for Circular Queue
We insert the new elements at the end of the queue using rear pointer. We first check if the queue is full or not.
Algorithm of Enqueue
if (isFull(queue)) {
print "Queue Overflow"
return
else
rear = (rear + 1) % size
arr[rear] = new_element
Implementation of Dequeue for Circular Queue
The elements are removed from the queue at the front of the queue. We first need to check whether queue is empty or not.
Algorithm of Enqueue
if (isEmpty(queue)) {
print "Queue Underflow"
return
else
front = (front + 1) % size
C++ Program to Implement Circular Queue Using Array
C++
// C++ program to implement the circular queue using array
#include <bits/stdc++.h>
// defining the max size of the queue
#define MAX_SIZE 5
using namespace std;
// class that represents queue
class Queue {
public:
// index pointers and data array
int front, rear;
int arr[MAX_SIZE];
// constructor to initialize the index pointers
Queue() { front = rear = 0; }
// checking if queue is empty
bool isEmpty()
{
if (front == rear)
return true;
return false;
}
// checking if the queue is full
bool isFull()
{
if ((rear + 1) % MAX_SIZE == front)
return true;
return false;
}
// enqueue operation
void enqueue(int val)
{
if (this->isFull()) {
printf("Queue Overflow!\n");
return;
}
rear = (rear + 1) % MAX_SIZE;
arr[rear] = val;
}
// dequeue operation
void dequeue()
{
if (this->isEmpty()) {
printf("Queue Underflow!\n");
return;
}
front = (front + 1) % MAX_SIZE;
}
// peek function
int peek()
{
if (this->isEmpty()) {
printf("Queue is Empty!\n");
return -1;
}
return arr[(front + 1) % MAX_SIZE];
}
// utility to print queue
void print()
{
if (this->isEmpty())
return;
for (int i = (front + 1) % MAX_SIZE; i < rear;
i = (i + 1) % MAX_SIZE) {
printf("%d ", arr[i]);
}
cout << arr[rear];
}
};
// driver code
int main()
{
Queue q;
q.enqueue(11);
q.enqueue(11);
q.enqueue(11);
q.enqueue(11);
q.enqueue(11);
q.enqueue(11);
q.dequeue();
q.dequeue();
q.enqueue(123);
q.print();
return 0;
}
OutputQueue Overflow!
Queue Overflow!
123
C++ Program for Circular Linked List Queue Implementation
This C++ program demonstrates the implementation of a queue using a circular linked list. It includes operations to enqueue (add) and dequeue (remove) elements, as well as check if the queue is empty or full. The circular nature of the linked list ensures efficient use of memory by reusing nodes, without the use of any extra concept like in the array implementation
C++
// C++ Program to Implement the circular queue using
// circular linked list
#include <bits/stdc++.h>
using namespace std;
// linked list node
class Node {
public:
int val;
Node* next;
Node(int v)
{
val = v;
next = nullptr;
}
};
// class representing circular queue
class Queue {
private:
// pointer to the end of the linked list.
Node* rear;
public:
// constructors
Queue() { rear = nullptr; }
// checking if the queue is empty
bool isEmpty()
{
if (!rear)
return true;
return false;
}
// enqueueing data in ciruclar linked list queue
void enqueue(int val)
{
// creating new node
Node* newNode = new Node(val);
// only condition for the queue overflow
// is when the dynamic memory allocation fails
if (!newNode) {
cout << "Queue Overflow!\n";
return;
}
// inserting depending on the multiple cases
if (this->isEmpty()) {
newNode->next = newNode;
rear = newNode;
}
else {
newNode->next = rear->next;
rear->next = newNode;
rear = newNode;
}
}
// dequeing data
void dequeue()
{
if (this->isEmpty()) {
cout << "Queue Underflow\n";
return;
}
// code for different cases
if (rear->next == rear) {
delete rear;
rear = nullptr;
}
else {
Node* temp = rear->next;
rear->next = temp->next;
delete temp;
}
}
// returning the first element in the queue
int peek()
{
if (this->isEmpty()) {
cout << "Queue is Empty!" << endl;
return -1;
}
return rear->next->val;
}
// utility function to print the queue
void print()
{
if (!rear) {
cout << "Queue is Empty!" << endl;
return;
}
Node* temp = rear->next;
do {
cout << temp->val << " ";
temp = temp->next;
} while (temp != rear->next);
cout << endl;
}
};
// driver code
int main()
{
Queue q;
q.enqueue(2);
q.enqueue(4);
q.enqueue(3);
q.enqueue(6);
q.enqueue(5);
cout << "Queue after all enqueue: ";
q.print();
q.dequeue();
cout << "Queue after one dequeue: ";
q.print();
return 0;
}
OutputQueue after all enqueue: 2 4 3 6 5
Queue after one dequeue: 4 3 6 5
Similar Reads
C++ Programming Language C++ is a computer programming language developed by Bjarne Stroustrup as an extension of the C language. It is known for is fast speed, low level memory management and is often taught as first programming language. It provides:Hands-on application of different programming concepts.Similar syntax to
5 min read
Non-linear Components In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
Spring Boot Tutorial Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
Object Oriented Programming in C++ Object Oriented Programming - As the name suggests uses objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the functions that operate on them so th
5 min read
Class Diagram | Unified Modeling Language (UML) A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Python Variables In Python, variables are used to store data that can be referenced and manipulated during program execution. A variable is essentially a name that is assigned to a value. Unlike many other programming languages, Python variables do not require explicit declaration of type. The type of the variable i
6 min read
Spring Boot Interview Questions and Answers Spring Boot is a Java-based framework used to develop stand-alone, production-ready applications with minimal configuration. Introduced by Pivotal in 2014, it simplifies the development of Spring applications by offering embedded servers, auto-configuration, and fast startup. Many top companies, inc
15+ min read
Backpropagation in Neural Network Back Propagation is also known as "Backward Propagation of Errors" is a method used to train neural network . Its goal is to reduce the difference between the modelâs predicted output and the actual output by adjusting the weights and biases in the network.It works iteratively to adjust weights and
9 min read
Polymorphism in Java Polymorphism in Java is one of the core concepts in object-oriented programming (OOP) that allows objects to behave differently based on their specific class type. The word polymorphism means having many forms, and it comes from the Greek words poly (many) and morph (forms), this means one entity ca
7 min read
3-Phase Inverter An inverter is a fundamental electrical device designed primarily for the conversion of direct current into alternating current . This versatile device , also known as a variable frequency drive , plays a vital role in a wide range of applications , including variable frequency drives and high power
13 min read