Queues in DSA: FIFO, Real Use Cases & Implementation

Last modified - 21-08-2026

Author - Krishna Shinde


If you're working through a DSA roadmap or any C++ tutorial series on data structures, the Queue is one you'll meet right after the Stack — and for good reason. Where a stack processes things last-in-first-out, a queue processes them in the exact order they arrived. That single idea shows up everywhere in real software, from task scheduling to how your messages get delivered.

This tutorial covers what a queue is, how it's implemented in C++, why a plain array-based queue has a hidden inefficiency, how the circular queue fixes it, and where queues actually show up in real systems — not just interview questions. As with any data structures topic, the goal is to understand the "why," not just memorize the operations.

Table of Contents

What Is a Queue?

A queue is a linear data structure that follows the FIFO (First In, First Out) principle. The first element added to the queue is the first one removed — exactly like a real-world line at a ticket counter. Whoever joins first gets served first; whoever joins last waits at the back.

Two ends define a queue:

This is the key difference from a stack, which only ever adds and removes from a single end (the top).

Core Queue Operations

OperationWhat It DoesTime Complexity
enqueue(x)Adds element x to the rear of the queueO(1)
dequeue()Removes and returns the front elementO(1)
peek() / front()Returns the front element without removing itO(1)
isEmpty()Checks whether the queue has any elementsO(1)
isFull()Checks whether a fixed-size queue has reached capacityO(1)

Implementing a Simple Queue in C++ (Array-Based)

Here's a straightforward array-based queue implementation:

#include <iostream>
using namespace std;

class Queue {
    int arr[5];
    int front, rear;

public:
    Queue() {
        front = -1;
        rear = -1;
    }

    void enqueue(int val) {
        if (rear == 4) {
            cout << "Queue is full" << endl;
            return;
        }

        if (front == -1) front = 0;

        arr[++rear] = val;
    }

    void dequeue() {
        if (front == -1 || front > rear) {
            cout << "Queue is empty" << endl;
            return;
        }

        cout << "Dequeued: " << arr[front++] << endl;
    }
};

int main() {
    Queue q;

    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);

    q.dequeue();
    q.dequeue();

    return 0;
}

Output:

Dequeued: 10
Dequeued: 20
queue in c++

The Hidden Problem With a Simple Queue

This works, but there's a catch. Every dequeue() moves front forward — it never resets. Once rear hits the end of the array, the queue reports "full," even if several slots at the beginning are now empty and unused.

Picture a 5-slot array. You enqueue 5 elements, then dequeue 3. Slots 0, 1, and 2 are free — but rear is still stuck at index 4, so enqueue() refuses to add anything new. The array's front portion is simply wasted space that never gets reused.

This is exactly the problem the circular queue was designed to solve.

Circular Queues in C++

A circular queue treats the underlying array as a ring instead of a straight line. When rear reaches the last index, the next enqueue wraps back around to index 0 (as long as that slot is actually free). This means every slot in the array gets reused instead of being abandoned once passed over.

The wraparound is done with the modulo operator:

rear = (rear + 1) % size;
#include <iostream>
using namespace std;

class CircularQueue {
    int arr[5];
    int front, rear, count, size;

public:
    CircularQueue() {
        front = 0;
        rear = -1;
        count = 0;
        size = 5;
    }

    void enqueue(int val) {
        if (count == size) {
            cout << "Queue is full" << endl;
            return;
        }

        rear = (rear + 1) % size;
        arr[rear] = val;
        count++;
    }

    void dequeue() {
        if (count == 0) {
            cout << "Queue is empty" << endl;
            return;
        }

        cout << "Dequeued: " << arr[front] << endl;
        front = (front + 1) % size;
        count--;
    }
};

int main() {
    CircularQueue q;

    for (int i = 1; i <= 5; i++) {
        q.enqueue(i * 10);
    }

    q.dequeue();
    q.dequeue();

    q.enqueue(60);
    q.enqueue(70);

    return 0;
}

Output:

Dequeued: 10
Dequeued: 20

Without the circular logic, enqueue(60) and enqueue(70) would have failed with "Queue is full," even though two slots were sitting empty. That single fix is the entire reason circular queues exist.

Other Types of Queues You Should Know

Deque (Double-Ended Queue)

Allows insertion and removal from both the front and the rear. C++'s standard library ships this as std::deque, and it's commonly used to implement both stacks and queues from a single structure.

Priority Queue

Elements are served based on priority rather than arrival order — the highest (or lowest) priority element is dequeued first, regardless of when it was added. C++'s std::priority_queue implements this using a heap internally. It's a separate topic worth its own deep dive.

Queue Time & Space Complexity

OperationTime ComplexitySpace Complexity
enqueue()O(1)O(1)
dequeue()O(1)O(1)
peek()O(1)O(1)
Overall queue (n elements)O(n)

Where Queues Actually Show Up

It's easy to treat queues as just another interview topic, but FIFO ordering is a core building block across real systems:

Advantages and Disadvantages of Queues

Advantages

Disadvantages

Conclusion

The queue is a small idea — first in, first out — but it's foundational to how scheduling, buffering, and traversal work under the hood. Understanding why the circular queue exists, not just how to code one, is what separates memorizing syntax from actually understanding data structures.

Next up: once queues feel solid, they become essential the moment you start Breadth-First Search on trees and graphs — the queue is what makes level-by-level traversal possible. We've already covered stacks in this DSA series; explore the rest of our C++ tutorial and DSA blogs, and follow Algoflame for more programming content.