Queue Data Structure in C++ with Real-Time Examples
Introduction to Queue
A Queue is a linear data structure that follows the principle:
- FIFO β First In, First Out
This means:
-
The element inserted first is removed first.
-
Just like a real-life queue of people waiting for service.
Queues are widely used in:
-
CPU scheduling
-
Printer spooling
-
Call center systems
-
Order processing systems
-
Networking packet management
Objective of This Lab
This lab introduces:
-
How to access the front and rear pointers
-
How to enqueue (insert) data
-
How to dequeue (delete) data
By the end of this session, you will understand both theory and implementation in C++.
Real-Time Example
π¦ Example: Bank Service Counter
Imagine customers standing in a line:
-
The first customer who enters the line gets served first.
-
New customers join at the rear.
-
Service happens from the front.
This is exactly how a queue works in programming.
The main operations are:
Enqueue β place an element at the tail of the queue;
Dequeue β take out an element form the front of the queue;
Delete β delete the whole queue
Queue Implementation Using Array in C++
We will implement Queue using:
-
Array
-
Front pointer
-
Rear pointer
-
Class-based structure (OOP approach)
π» Complete C++ Implementation
#include <iostream>
using namespace std;
#define SIZE 5
class Queue {
private:
int arr[SIZE];
int front;
int rear;
public:
// Constructor
Queue() {
front = -1;
rear = -1;
}
// Check if queue is empty
bool isEmpty() {
return (front == -1 || front > rear);
}
// Check if queue is full
bool isFull() {
return (rear == SIZE - 1);
}
// Enqueue operation
void enqueue(int value) {
if (isFull()) {
cout << "Queue Overflow! Cannot insert " << value << endl;
return;
}
if (front == -1)
front = 0;
arr[++rear] = value;
cout << value << " inserted into queue." << endl;
}
// Dequeue operation
void dequeue() {
if (isEmpty()) {
cout << "Queue Underflow! Queue is empty." << endl;
return;
}
cout << arr[front++] << " removed from queue." << endl;
}
// Display queue elements
void display() {
if (isEmpty()) {
cout << "Queue is empty." << endl;
return;
}
cout << "Queue elements: ";
for (int i = front; i <= rear; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// Access front element
void getFront() {
if (!isEmpty())
cout << "Front element: " << arr[front] << endl;
}
// Access rear element
void getRear() {
if (!isEmpty())
cout << "Rear element: " << arr[rear] << endl;
}
};
int main() {
Queue q;
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.display();
q.getFront();
q.getRear();
q.dequeue();
q.display();
return 0;
}

Activity 1:
Implement an array-based FIFO Queue
#include <iostream>
using namespace std;
class Queue // Renamed properly to Queue
{
private:
int size; // capacity
int *q; // dynamic array
int front; // front index
int rear; // rear index
public:
// Default constructor
Queue()
{
size = 10;
q = new int[size];
front = -1;
rear = -1;
}
// Overloaded constructor
Queue(int x)
{
size = x;
q = new int[size];
front = -1;
rear = -1;
}
// Destructor to free memory
~Queue()
{
delete[] q;
}
// Check if queue is empty
bool is_empty()
{
return (front == -1);
}
// Check if queue is full
bool is_full()
{
return (rear == size - 1);
}
// Display queue elements
void display()
{
if (is_empty())
{
cout << "\nQueue is empty.";
}
else
{
for (int i = front; i <= rear; i++)
{
cout << "\nValue at index " << i << " is: " << q[i];
}
}
}
// Enqueue operation
void enqueue(int x)
{
if (is_full())
{
cout << "\nNo space. Queue is full.";
}
else
{
if (is_empty())
{
front = rear = 0;
}
else
{
rear++;
}
q[rear] = x;
}
}
// Dequeue operation
int dequeue()
{
if (is_empty())
{
cout << "\nQueue is already empty.";
return -1;
}
else
{
int x = q[front];
if (front == rear)
{
front = rear = -1;
}
else
{
front++;
}
return x;
}
}
};
int main()
{
Queue q1; // Default constructor (size 10)
Queue q2(5); // Size 5
Queue q3(15); // Size 15
q1.enqueue(5);
q2.enqueue(7);
q3.enqueue(6);
int x = q2.dequeue();
cout << "\nDequeued element from q2 is: " << x;
return 0;
}
Activity 3:
Consider the activity-1 where there was an issue of space and to resolve this we applied the shifting. The problem with shifting is that it increases the complexity. The solution of this is circular queue. Circular Queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. We apply the formula (Rear=(Rear+1) mod Queue Size) to move the rear to next index.
Implement an Array based circular Queue that is generic in nature (use template classes), apply proper checks of Queue Full and Queue Empty before Enque and DeQue operations.
Below is the complete implementation of a Generic (Template-Based) Circular Queue using Array in C++.
This implementation:
-
Uses template class (generic in nature)
-
Applies FIFO principle
-
Uses circular logic:
rear = (rear + 1) % size -
Properly checks:
-
Queue Full
-
Queue Empty
-
-
Avoids shifting (efficient O(1) operations)
#include <iostream>
using namespace std;
template <class T>
class CircularQueue {
private:
T* arr; // Dynamic array
int front;
int rear;
int capacity;
int count; // Number of elements in queue
public:
// Constructor
CircularQueue(int size) {
capacity = size;
arr = new T[capacity];
front = 0;
rear = -1;
count = 0;
}
// Destructor
~CircularQueue() {
delete[] arr;
}
// Check if queue is empty
bool isEmpty() {
return (count == 0);
}
// Check if queue is full
bool isFull() {
return (count == capacity);
}
// Enqueue operation
void enqueue(T value) {
if (isFull()) {
cout << "Queue Overflow! Cannot insert element.\n";
return;
}
rear = (rear + 1) % capacity; // Circular increment
arr[rear] = value;
count++;
cout << value << " inserted into circular queue.\n";
}
// Dequeue operation
T dequeue() {
if (isEmpty()) {
cout << "Queue Underflow! Queue is empty.\n";
return T(); // Return default value
}
T value = arr[front];
front = (front + 1) % capacity; // Circular increment
count--;
return value;
}
// Get front element
T getFront() {
if (isEmpty()) {
cout << "Queue is empty.\n";
return T();
}
return arr[front];
}
// Get rear element
T getRear() {
if (isEmpty()) {
cout << "Queue is empty.\n";
return T();
}
return arr[rear];
}
// Display queue elements
void display() {
if (isEmpty()) {
cout << "Queue is empty.\n";
return;
}
cout << "Circular Queue elements: ";
for (int i = 0; i < count; i++) {
cout << arr[(front + i) % capacity] << " ";
}
cout << endl;
}
};
int main() {
CircularQueue<int> q(5);
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.enqueue(40);
q.enqueue(50);
q.display();
cout << "Dequeued element: " << q.dequeue() << endl;
cout << "Dequeued element: " << q.dequeue() << endl;
q.display();
q.enqueue(60);
q.enqueue(70);
q.display();
cout << "Front element: " << q.getFront() << endl;
cout << "Rear element: " << q.getRear() << endl;
return 0;
}

3) Graded Lab Tasks
Lab Task 1
Implement the methods developed in Activity 1 for Dynmaic Queue i.e. Linked Implementation of the Queue.
Lab Task 2
Implement the Deque in a linked list.
π Understanding Front and Rear Pointers
| Pointer | Purpose |
|---|---|
| Front | Points to first element |
| Rear | Points to last element |
When:
-
front > rearβ Queue becomes empty. -
rear == SIZE - 1β Queue becomes full.
β±οΈ Time Complexity
| Operation | Complexity |
|---|---|
| Enqueue | O(1) |
| Dequeue | O(1) |
| Access | O(1) |
| Display | O(n) |
Advantages of Queue
-
Simple structure
-
Efficient insertion and deletion
-
Useful in scheduling and buffering systems
Limitations
-
Fixed size in array implementation
-
Wasted memory after multiple dequeues (in simple queue)
-
Circular queue solves this limitation
FAQ Section
What is FIFO in Queue?
FIFO stands for First In First Out, meaning the first inserted element is removed first.
What is the difference between Stack and Queue?
Stack follows LIFO, while Queue follows FIFO.
What are real-world uses of Queue?
CPU scheduling, order processing, call management systems.
π Conclusion
The Queue Data Structure is fundamental in computer science. Understanding:
-
Front and rear pointers
-
Enqueue operation
-
Dequeue operation
builds a strong foundation for advanced data structures like circular queue, priority queue, and deque.
Mastering queue implementation in C++ prepares students for:
-
Lab exams
-
Coding interviews
-
Competitive programming