C# - Queue<T>

In C#, a 'Queue<T>' is a collection class that represents a data structure following the first-in, first-out (FIFO) principle. It resides within the System.Collections.Generic namespace and is employed for managing a collection of items in the order they were initially added. Here's an overview of 'Queue':

'Queue' adheres to the First-In, First-Out (FIFO) principle, meaning that the first element added to the queue will be the first one to be removed.

To include elements in a 'Queue<T>', you utilize the Enqueue method, which appends new elements to the rear of the queue.

For extracting elements from a 'Queue<T>', the Dequeue method is employed. It removes and returns the element that was initially added to the queue.

Queue Characteristics:

Here are some key characteristics of the 'Queue<T>' class in C#:

  1. First-In, First-Out (FIFO): A Queue works like a real-world line or queue. The thing that goes in first is the first to come out.
  2. Enqueue: You add items to the end of the Queue, just like adding people to the back of a line.
  3. Dequeue: You remove items from the front of the Queue, similar to the first person leaving a real-world queue.
  4. Peek: You can look at the item at the front without removing it, like taking a quick glance at the first person in line.
  5. Count: You can check how many items are in the Queue using the "Count" property, helping you keep track of tasks or items waiting.
  6. Clear: If you want to start fresh and remove all items from the Queue, you can use the "Clear" method, like clearing a whole line.
  7. Exception Handling: Be careful not to dequeue from an empty Queue, as it can cause an error. Check the count before dequeuing to avoid issues.

These characteristics make a Queue a useful tool for managing tasks or items in a specific order, just like waiting in line!

1. Push into 'Queue<T>':

To add elements to a 'Queue<T>' in C#, you use the Enqueue method. This method adds an element to the back of the queue. Here's how you can push elements into a 'Queue<T>':


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> tasks = new Queue<string>();

        // Enqueue elements into the queue
        tasks.Enqueue("Task 1");
        tasks.Enqueue("Task 2");
        tasks.Enqueue("Task 3");

        Console.WriteLine("Tasks enqueued into the queue:");
        foreach (string task in tasks)
        {
            Console.WriteLine(task);
        }
    }
}

In this example, we create a Queue<string> named tasks and use the Enqueue method to add three task strings to the queue. The tasks are added to the back of the queue. The resulting display will present the tasks in the sequence they were initially added.

Keep in mind that the Enqueue operation adheres to the First-In, First-Out (FIFO) characteristic of a queue, signifying that the foremost element inserted will be the initial one to be taken out during the dequeuing process.

2. Pop from 'Queue<T>':

In a 'Queue<T>', the operation to remove and retrieve the front element is called "dequeue" rather than "pop," as it follows the First-In, First-Out (FIFO) behavior. Here's how you can dequeue elements from a 'Queue<T>' in C#:


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> tasks = new Queue<string>();

        // Enqueue elements into the queue
        tasks.Enqueue("Task 1");
        tasks.Enqueue("Task 2");
        tasks.Enqueue("Task 3");

        // Dequeue elements from the queue
        string dequeuedTask1 = tasks.Dequeue();
        string dequeuedTask2 = tasks.Dequeue();

        Console.WriteLine($"Dequeued task 1: {dequeuedTask1}");
        Console.WriteLine($"Dequeued task 2: {dequeuedTask2}");

        Console.WriteLine("Remaining tasks in the queue:");
        foreach (string task in tasks)
        {
            Console.WriteLine(task);
        }
    }
}

In this illustration, we establish a 'Queue<string>' labeled as "tasks," enqueue three task strings, and subsequently employ the Dequeue method to eliminate the initial two tasks from the queue. The tasks that have been dequeued are exhibited in the output, along with a display of the tasks that remain within the queue.

Keep in mind that the Dequeue operation extracts and provides the foremost element in the queue, adhering to the First-In, First-Out (FIFO) principle. If you attempt to dequeue from an empty queue, it will trigger an InvalidOperationException. To prevent this issue, you can first inspect the Count property before proceeding with dequeuing:


if (queue.Count > 0)
{
    var dequeuedItem = queue.Dequeue();
    Console.WriteLine($"Dequeued item: {dequeuedItem}");
}
else
{
    Console.WriteLine("Queue is empty.");
}

3. Peek of a 'Queue<T>':

To peek at the front element of a 'Queue<T>' in C#, without removing it, you can use the Peek method. Here's how you can use the Peek method to see the front element of the queue:


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> tasks = new Queue<string>();

        // Enqueue elements into the queue
        tasks.Enqueue("Task 1");
        tasks.Enqueue("Task 2");
        tasks.Enqueue("Task 3");

        // Peek at the front element without removing it
        string frontTask = tasks.Peek();
        Console.WriteLine($"Front task: {frontTask}");

        Console.WriteLine("Tasks in the queue:");
        foreach (string task in tasks)
        {
            Console.WriteLine(task);
        }
    }
}

In this example, we create a Queue<string> named "tasks," where we enqueue three task strings. Subsequently, we employ the Peek method to observe the frontmost task without taking it out. The foremost task is revealed in the output, alongside a listing of all the tasks presently contained in the queue.

Please bear in mind that the Peek operation grants you the capability to examine the leading element without altering the queue's state. Should you attempt to peek at an empty queue, it will trigger an InvalidOperationException. To avert this situation, it's advisable to first examine the Count property before performing a peek operation:


if (queue.Count > 0)
{
    var frontItem = queue.Peek();
    Console.WriteLine($"Front item: {frontItem}");
}
else
{
    Console.WriteLine("Queue is empty.");
}

The Peek method comes in handy when you want to take a look at the first item in the queue before deciding what to do next or doing anything else with it.

4. Implementing First-In-First-Out (FIFO) behavior:

Let's implement an example that demonstrates the First-In, First-Out (FIFO) behavior using the 'Queue<T>' class in C#. In this example, we'll pretend to have a basic printer queue. We add print jobs to the queue, and they get printed in the same order they were added.


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> printerQueue = new Queue<string>();

        // Simulate adding print jobs to the queue
        EnqueuePrintJob(printerQueue, "Document1.txt");
        EnqueuePrintJob(printerQueue, "Document2.txt");
        EnqueuePrintJob(printerQueue, "Document3.txt");

        // Process print jobs in the order they were added
        ProcessPrintJobs(printerQueue);
    }

    static void EnqueuePrintJob(Queue<string> queue, string documentName)
    {
        Console.WriteLine($"Enqueuing print job: {documentName}");
        queue.Enqueue(documentName);
    }

    static void ProcessPrintJobs(Queue<string> queue)
    {
        Console.WriteLine("Processing print jobs:");
        while (queue.Count > 0)
        {
            string printJob = queue.Dequeue();
            Console.WriteLine($"Printing: {printJob}");
        }
    }
}

In this example:

  1. We create a Queue<string> named printerQueue to simulate a printer queue.
  2. The EnqueuePrintJob method is used to simulate adding a print job to the queue.
  3. The ProcessPrintJobs method is used to simulate processing the print jobs in the order they were added.

When you run the program, you'll see that the print jobs are processed in the order they were enqueued, demonstrating the First-In, First-Out (FIFO) behavior of the 'Queue<T>' class:


Enqueuing print job: Document1.txt
Enqueuing print job: Document2.txt
Enqueuing print job: Document3.txt
Processing print jobs:
Printing: Document1.txt
Printing: Document2.txt
Printing: Document3.txt

This example illustrates how the 'Queue<T>' class maintains the order of elements based on the order they were enqueued, which is essential for achieving First-In, First-Out (FIFO) behavior.

5. Methods and properties of Queue:

Here are some of the commonly used methods and properties of the 'Queue<T>' class in C#:

Methods:
  1. 'Enqueue(T item)': Adds an item to the back (end) of the queue.
  2. 'Dequeue()': Removes and returns the front (start) item of the queue.
  3. 'Peek()': Returns the front item of the queue without removing it.
  4. 'Clear()': Removes all items from the queue.
  5. 'Contains(T item)': Checks if the queue contains a specific item.
  6. 'ToArray()': Copies the items of the queue to a new array.
Properties:
  1. 'Count': Gets the number of items currently in the queue.

Here's an example that demonstrates the usage of these methods and properties:


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> tasks = new Queue<string>();

        // Enqueue elements into the queue
        tasks.Enqueue("Task 1");
        tasks.Enqueue("Task 2");
        tasks.Enqueue("Task 3");

        // Dequeue elements from the queue
        string dequeuedTask1 = tasks.Dequeue();
        string dequeuedTask2 = tasks.Dequeue();

        Console.WriteLine($"Dequeued task 1: {dequeuedTask1}");
        Console.WriteLine($"Dequeued task 2: {dequeuedTask2}");

        // Peek at the front task without removing it
        string frontTask = tasks.Peek();
        Console.WriteLine($"Front task: {frontTask}");

        // Display the count of remaining tasks in the queue
        Console.WriteLine($"Remaining tasks count: {tasks.Count}");

        // Clear the queue
        tasks.Clear();
        Console.WriteLine($"Queue cleared. Remaining tasks count: {tasks.Count}");
    }
}

In this example, we use the Enqueue, Dequeue, and Peek methods to add, remove, and peek at elements in the queue. We also use the Count property to check how many tasks are left in the queue, and the Clear method to remove all tasks from the queue.

Remember that a 'Queue<T>' follows the First-In, First-Out (FIFO) behavior, so the order of enqueuing and dequeuing matters.