Open In App

Deque in C#

Last Updated : 19 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

C# Deque means double-ended queue. It is a linear data structure that allows us to add or remove elements from both the front and the end. A deque is more flexible than the normal queue where we can only add elements from the back and remove them from the front.

  • Elements can be added or removed from both the front and end.
  • The deque can grow and shrink dynamically.
  • We can use deque as a Stack or Queue depending upon the use cases.

Example: This example demonstrates how to add elements to both the front and the back of the deque

C#
// demonstrating Dequeue
using System;
using System.Collections.Generic;

class Geeks
{
    static void Main()
    {
        // Create a LinkedList to simulate a Deque
        LinkedList<int> d = new LinkedList<int>();

        // Add elements to the front 
        d.AddFirst(10);
        d.AddFirst(20);  
        d.AddFirst(30);  

        // Add elements to the back 
        d.AddLast(50);  
        // Iterate over the deque and print each element
        Console.WriteLine("Elements in the Deque:");
        foreach (var i in d)
        {
            Console.WriteLine(i);
        }
    }
}

Output
Elements in the Deque:
30
20
10
50

Why use a Deque?

Deque is very useful in scenarios where we need to manage the data from both the ends. Some of the common applications of deque are listed below:

  • Job Scheduling: Managing tasks with varying priorities.
  • Sliding Window Algorithms: Solving problems like finding the maximum in a subarray.
  • Breadth-First Search (BFS): Traversing graphs or trees.

Types of Deque

The below diagram demonstrates the types of deque in C#.

Types-of-Dequeue


  • Input-Restricted deque: In this, insertion is allowed only at one end, but deletion can be done from both ends.
  • Output-Restricted deque: In this, deletion is allowed only at one end, but insertion can be done from both ends.
  • Double-Ended deque: In this, insertion and deletion are allowed at both ends.

Declaration of Deque

In C#, there is no built-in deque class. We can create deque with the help of LinkedList<T> class or by using Queue<T> class.

Note: Queue<T> can also create a deque, but it is not ideal for operation at both the ends due to limitations.

Using LinkedList<T> (Recommended Approach)

A LinkedList<T> is a good choice for a deque because it lets us add or remove items quickly from both the front and back.

Declaration of deque using LinkedList<T>

LinkedList<int> deque = new LinkedList<int>();

Example: This example, demonstrates how to add elements to both the front and back and then iterating through the list

C#
// demonstrates using LinkedList<T> class
using System;
using System.Collections.Generic;
class Geeks
{
    static void Main()
    {
        // Declare a LinkedList as a Deque
        LinkedList<int> d = new LinkedList<int>();

        // Add elements to the front (AddFirst)
        d.AddFirst(10);
        d.AddFirst(20);
        d.AddFirst(30);

        // Add elements to the back (AddLast)
        d.AddLast(40);
        d.AddLast(50);

        // Iterate over the deque and print elements
        Console.WriteLine("Deque Elements:");
        foreach (var i in d)
        {
            Console.WriteLine(i);
        }
    }
}

Output
Deque Elements:
30
20
10
40
50

Implementing Deque in C#

C# provides Three approaches to implement deque in C#, we are going to discuss about each approach one by one

1. Implementing Deque using Arrays

An Array-based deque can be implemented by managing a fixed-size array and keeping track of front and rear pointers.

Implementation:

C#
// demonstrating how to implement dequeue 
// using array
using System;

public class SimpleDequeue
{
    private int[] arr;
    private int front;
    private int rear;
    private int size;

    public SimpleDequeue(int capacity)
    {
        arr = new int[capacity];
        front = -1;
        rear = -1;
        size = 0;
    }

    // Add to the front of the deque
    public void EnqueueFront(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Queue is full");
            return;
        }

        if (front == -1) // If it's the first element
        {
            front = 0;
            rear = 0;
        }
        else if (front == 0) // Wrap around if front is at 0
        {
            front = arr.Length - 1;
        }
        else
        {
            front--;
        }
        arr[front] = value;
        size++;
    }

    // Add to the rear of the deque
    public void EnqueueRear(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Queue is full");
            return;
        }
        // If it's the first element
        if (front == -1) 
        {
            front = 0;
            rear = 0;
        }
        else
        {
            // Wrap around if rear is at the end
            rear = (rear + 1) % arr.Length; 
        }
        arr[rear] = value;
        size++;
    }

    // Remove from the front of the deque
    public int DequeueFront()
    {
        if (size == 0)
        {
            Console.WriteLine("Queue is empty");
            return -1;
        }

        int removedValue = arr[front];
        // Only one element in the queue
        if (front == rear) 
        {
            front = -1;
            rear = -1;
        }
        else
        {
             // Move the front pointer
            front = (front + 1) % arr.Length;
        }
        size--;
        return removedValue;
    }

    // Remove from the rear of the deque
    public int DequeueRear()
    {
        if (size == 0)
        {
            Console.WriteLine("Queue is empty");
            return -1;
        }

        int removedValue = arr[rear];
        // Only one element in the queue
        if (front == rear) 
        {
            front = -1;
            rear = -1;
        }
        else
        {
            // Move the rear pointer
            rear = (rear - 1 + arr.Length) % arr.Length; 
        }
        size--;
        return removedValue;
    }

    // Display the current elements in the deque
    public void Display()
    {
        if (size == 0)
        {
            Console.WriteLine("Queue is empty");
            return;
        }

        int i = front;
        for (int count = 0; count < size; count++)
        {
            Console.Write(arr[i] + " ");
            i = (i + 1) % arr.Length;
        }
        Console.WriteLine();
    }
}

class Geeks
{
    static void Main()
    {
        SimpleDequeue dq = new SimpleDequeue(5);

        // Adding elements to both ends
        dq.EnqueueRear(10);
        dq.EnqueueRear(20);
        dq.EnqueueFront(30);
        dq.EnqueueFront(40);
        dq.Display(); 

        // Removing elements from both ends
        Console.WriteLine("Dequeue from front: " + dq.DequeueFront()); 
        Console.WriteLine("Dequeue from rear: " + dq.DequeueRear());  
        dq.Display();
    }
}

Output
40 30 10 20 
Dequeue from front: 40
Dequeue from rear: 20
30 10 

2. Implementing Deque using LinkedList

LinkedList<T> class is an ideal choice for deque because it allows fast insertion and deletion operations from both ends. The LinkedList<T> stores elements in a doubly-linked list, both ends can be accessed and modified in constant time O(1).

Implementation:

C++
// demonstrating how to implement dequeue 
// using LinkedList

using System;
using System.Collections.Generic;

class Geeks {
  static void Main() {
    LinkedList<int> d = new LinkedList<int>();

    // Adding element to the front of the dequeue
    d.AddFirst(10);
    d.AddFirst(20);

    // Adding element to the back of the dequeue
    d.AddLast(30);
    d.AddLast(40);

    // Removing element from the front of the dequeue
    int front = d.First.Value;
    d.RemoveFirst();

    // Removing element from the back of the dequeue
    int back = d.Last.Value;
    d.RemoveLast();

    // Display the remaining elements of the dequeue
    foreach (int i in d) {
      Console.WriteLine(i);
    }
  }
}

Output:

Output

3. Implementing Deque Using List<T>

A list<T> is dynamic array, it can efficiently access elements by index. This approach is less efficient for the front operations (add/remove) compared to the LinkedList<T> approach but can still be useful for small lists.

Implementation:

C#
// demonstrating how to implement dequeue 
// using List
using System;
using System.Collections.Generic;

class Geeks{
  static void Main() {
    List<int> d = new List<int>();

    // Adding elements to the front of the dequeue
    d.Insert(0, 10);
    d.Insert(0, 20);

    // Adding elements to the back of the dequeue
    d.Add(30);
    d.Add(40);

    // Removing element from the front of the dequeue
    int front = d[0];
    d.RemoveAt(0);

    // Removing element from the back of the dequeue
    int back = d[d.Count - 1];
    d.RemoveAt(d.Count - 1);

    // Display the remaining elements of the dequeue
    foreach (int value in d) {
      Console.WriteLine(value);
    }
  }
}

Output
10
30

Performing Various Operations on Deque

1. Adding Elements to the Front

We can use the EnqueueFront() to add elements to the front of the deque.

Example: This example demonstrates how to insert elements to the front of the deque.

C#
// demonstrating the working of EnqueueFront()

using System;
public class SimpleDequeue
{
    private int[] arr;
    private int front;
    private int rear;
    private int size;

    public SimpleDequeue(int capacity)
    {
        arr = new int[capacity];
        front = -1;
        rear = -1;
        size = 0;
    }

    // Add to the front of the deque
    public void EnqueueFront(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Deque is full!");
            return;
        }
        // If it's the first element
        if (front == -1) 
        {
            front = 0;
            rear = 0;
        }
         // Wrap around if front is at 0
        else if (front == 0)
        {
            front = arr.Length - 1;
        }
        else
        {
            front--;
        }
        arr[front] = value;
        size++;
    }

    // Display the current elements in the deque
    public void Display()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return;
        }

        int i = front;
        for (int count = 0; count < size; count++)
        {
            Console.Write(arr[i] + " ");
            i = (i + 1) % arr.Length;
        }
        Console.WriteLine();
    }
}

class Geeks
{
    static void Main()
    {
        SimpleDequeue dq = new SimpleDequeue(5);

        // Add elements to the front
        dq.EnqueueFront(10);
        dq.EnqueueFront(20);
        dq.EnqueueFront(30);

        // Display the deque after adding to the front
        dq.Display();  
    }
}

Output:

Output

2. Adding Element to the Rear

We can use the EnqueueRear() to add elements to the end of the deque.

Example:

C#
using System;

public class SimpleDequeue
{
    private int[] arr;
    private int front;
    private int rear;
    private int size;

    public SimpleDequeue(int capacity)
    {
        arr = new int[capacity];
        front = -1;
        rear = -1;
        size = 0;
    }

    // Adding element to the rear of the dequeue
    public void EnqueueRear(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Deque is full!");
            return;
        }
        // If it's the first element
        if (front == -1) 
        {
            front = 0;
            rear = 0;
        }
        else
        {
            // Wrap around if rear is at the end
            rear = (rear + 1) % arr.Length; 
        }
        arr[rear] = value;
        size++;
    }

    // Displaying the current elements in the dequeue
    public void Display()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return;
        }

        int i = front;
        for (int count = 0; count < size; count++)
        {
            Console.Write(arr[i] + " ");
            i = (i + 1) % arr.Length;
        }
        Console.WriteLine();
    }
}

class Geeks
{
    static void Main()
    {
        SimpleDequeue dq = new SimpleDequeue(5);

        // Adding elements to the rear
        dq.EnqueueRear(10);
        dq.EnqueueRear(20);
        dq.EnqueueRear(30);

        // Displaying the deque after adding to the rear
        dq.Display();  
    }
}

Output:

Output

3. Removing Elements from the Front

We can use the dequeFront() method to remove elements from the front of the deque.

Example:

C#
using System;

public class SimpleDequeue
{
    private int[] arr;
    private int front;
    private int rear;
    private int size;

    public SimpleDequeue(int capacity)
    {
        arr = new int[capacity];
        front = -1;
        rear = -1;
        size = 0;
    }

    // Add to the rear of the deque
    public void EnqueueRear(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Deque is full!");
            return;
        }
        
        // If it's the first element
        if (front == -1)
        {
            front = 0;
            rear = 0;
        }
        else
        {
            rear = (rear + 1) % arr.Length;
        }
        
        arr[rear] = value;
        size++;
    }

    // Remove from the front of the deque
    public int DequeueFront()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return -1;
        }

        int removedValue = arr[front];
        if (front == rear) // Only one element in the deque
        {
            front = -1;
            rear = -1;
        }
        else
        {
            // Move the front pointer
            front = (front + 1) % arr.Length; 
        }
        size--;
        return removedValue;
    }

    // Display the current elements in the deque
    public void Display()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return;
        }

        int i = front;
        for (int count = 0; count < size; count++)
        {
            Console.Write(arr[i] + " ");
            i = (i + 1) % arr.Length;
        }
        Console.WriteLine();
    }
}

class Geeks
{
    static void Main()
    {
        SimpleDequeue dq = new SimpleDequeue(5);

        // Add elements to the rear
        dq.EnqueueRear(10);
        dq.EnqueueRear(20);
        dq.EnqueueRear(30);

        // Remove elements from the front
        Console.WriteLine($"Removed from front: {dq.DequeueFront()}");
        dq.Display();
    }
}

Output:

Output

4. Removing Elements from the Rear

We can use the dequeRear() method to remove elements from the end of the deque.

Example:

C#
using System;

public class SimpleDequeue
{
    private int[] arr;
    private int front;
    private int rear;
    private int size;

    public SimpleDequeue(int capacity)
    {
        arr = new int[capacity];
        front = -1;
        rear = -1;
        size = 0;
    }

    // Add to the rear of the deque
    public void EnqueueRear(int value)
    {
        if (size == arr.Length)
        {
            Console.WriteLine("Deque is full!");
            return;
        }
        
        // If it's the first element
        if (front == -1)
        {
            front = 0;
            rear = 0;
        }
        else
        {
            rear = (rear + 1) % arr.Length;
        }
        
        arr[rear] = value;
        size++;
    }

    // Remove from the rear of the deque
    public int DequeueRear()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return -1;
        }

        int removedValue = arr[rear];
        // Only one element in the deque
        if (front == rear) 
        {
            front = -1;
            rear = -1;
        }
        else
        {
            // Move the rear pointer
            rear = (rear - 1 + arr.Length) % arr.Length; 
        }
        size--;
        return removedValue;
    }

    // Display the current elements in the deque
    public void Display()
    {
        if (size == 0)
        {
            Console.WriteLine("Deque is empty!");
            return;
        }

        int i = front;
        for (int count = 0; count < size; count++)
        {
            Console.Write(arr[i] + " ");
            i = (i + 1) % arr.Length;
        }
        Console.WriteLine();
    }
}

class Geeks
{
    static void Main()
    {
        SimpleDequeue dq = new SimpleDequeue(5);

        // Add elements to the rear
        dq.EnqueueRear(10);
        dq.EnqueueRear(20);
        dq.EnqueueRear(30);

        // Remove elements from the rear
        Console.WriteLine($"Removed from rear: {dq.DequeueRear()}"); 
        dq.Display();  
    }
}

Output:

Output

Similar Reads