C++ queues


Introduction

In C++, a queue is a container adaptor in the C++ Standard Library that follows the First In First Out (FIFO) principle. It is defined in the <queue> header file. A queue is a data structure where elements are added at the back (enqueue operation) and removed from the front (dequeue operation). This makes queues useful for tasks that require ordered processing, like task scheduling, simulation, or message handling.

Queues are typically implemented using underlying containers like std::deque or std::list. However, the std::queue provides a simplified interface for working with them.


Key Features of std::queue

  • FIFO (First In First Out): The first element added to the queue is the first one to be removed.
  • Enqueue and Dequeue Operations: Elements are added to the back and removed from the front.
  • No Random Access: Queues do not allow direct access to the middle or random elements. Only the front and back elements can be accessed.
  • Underlying Container: The std::queue uses another container (like std::deque or std::list) to store the elements.
  • Efficient: Inserting and removing elements at the front and back are efficient operations (constant time).

Syntax

To declare a queue:

std::queue<T> queue_name;

Where:

  • T: Type of the elements (e.g., int, std::string).

You can also initialize a queue with a specific container:

std::queue<T, Container> queue_name;

Where Container can be std::deque (default) or std::list.


Declaring and Initializing a Queue

Example 1: Basic Queue Declaration and Initialization

#include <iostream>
#include <queue>

int main() {
    // Declare a queue of integers
    std::queue<int> q;

    // Enqueue elements
    q.push(10);
    q.push(20);
    q.push(30);

    // Displaying the front element
    std::cout << "Front of the queue: " << q.front() << std::endl;  // Output: 10

    return 0;
}

Explanation:

  • push() is used to add elements to the queue.
  • front() returns the element at the front of the queue.

Important Member Functions of std::queue

1. push()

Adds an element to the back of the queue.

q.push(40);  // Adds 40 to the back of the queue

2. pop()

Removes the element at the front of the queue.

q.pop();  // Removes the front element from the queue

3. front()

Returns a reference to the element at the front of the queue.

std::cout << "Front element: " << q.front() << std::endl;

4. back()

Returns a reference to the element at the back of the queue.

std::cout << "Back element: " << q.back() << std::endl;

5. size()

Returns the number of elements in the queue.

std::cout << "Size of the queue: " << q.size() << std::endl;

6. empty()

Checks if the queue is empty.

if (q.empty()) {
    std::cout << "The queue is empty!" << std::endl;
} else {
    std::cout << "The queue is not empty!" << std::endl;
}

Iterating Through a Queue

Unlike other containers, such as vectors or lists, queues do not allow direct access to their elements via iterators. To iterate through a queue, you need to pop elements one by one and process them.

Example 1: Iterating by Popping Elements

#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    // Iterating through the queue by popping elements
    while (!q.empty()) {
        std::cout << q.front() << " ";  // Print the front element
        q.pop();  // Remove the front element
    }

    return 0;
}

Explanation:

  • We use pop() to remove the front element until the queue is empty.
  • The front() function provides access to the first element.

Advantages of std::queue Over Other Containers

  1. FIFO Order: Queues ensure that elements are processed in the order they were added, making them ideal for tasks that require sequential processing, such as job scheduling.
  2. Efficient Operations: Insertion and removal operations are performed in constant time, making them efficient for large datasets.
  3. Simple Interface: std::queue provides a minimal interface, focusing on the essential operations required for queue management without exposing unnecessary details.

When to Use std::queue

Use std::queue when:

  • You need to store and process data in a First In First Out (FIFO) manner.
  • The order of processing is critical, such as handling tasks in a scheduling system or processing messages.
  • You want efficient operations for adding/removing elements from the front and back.

Real-World Applications of Queues

  1. Task Scheduling: In operating systems, queues are used to manage processes or tasks that need to be executed. The tasks are processed in the order they arrive.
  2. Printer Queues: A printer queue stores print jobs and processes them in the order they are received.
  3. Message Handling: In communication systems, messages are stored in a queue and processed in the order they arrive.
  4. Breadth-First Search (BFS): In graph algorithms like BFS, a queue is used to explore nodes level by level.