A Deque Class in C#

A Deque (double-ended queue) is a data structure that allows insertion and deletion of elements from both ends. In C#, while there's no built-in Deque class, we can implement one using a doubly-linked list or utilize existing collections like LinkedList<T> to achieve deque functionality.

The key advantage of a deque is its flexibility ? you can add and remove elements from both the front and back, making it suitable for scenarios like implementing sliding window algorithms, browser history, or undo/redo operations.

Deque Operations

A typical deque supports the following core operations −

  • AddFirst() ? adds an element to the front

  • AddLast() ? adds an element to the back

  • RemoveFirst() ? removes an element from the front

  • RemoveLast() ? removes an element from the back

  • PeekFirst() ? views the front element without removing it

  • PeekLast() ? views the back element without removing it

Deque Structure 10 20 30 40 FRONT BACK Add/Remove Add/Remove

Using LinkedList as Deque

C#'s LinkedList<T> class provides all the methods needed to implement deque functionality −

using System;
using System.Collections.Generic;

class DequeExample {
   public static void Main() {
      LinkedList<int> deque = new LinkedList<int>();
      
      // Add elements to both ends
      deque.AddLast(20);   // Add to back: [20]
      deque.AddFirst(10);  // Add to front: [10, 20]
      deque.AddLast(30);   // Add to back: [10, 20, 30]
      deque.AddFirst(5);   // Add to front: [5, 10, 20, 30]
      
      Console.WriteLine("Deque contents:");
      foreach (int item in deque) {
         Console.Write(item + " ");
      }
      Console.WriteLine();
      
      // Peek at both ends
      Console.WriteLine("First element: " + deque.First.Value);
      Console.WriteLine("Last element: " + deque.Last.Value);
      
      // Remove from both ends
      deque.RemoveFirst(); // Remove 5: [10, 20, 30]
      deque.RemoveLast();  // Remove 30: [10, 20]
      
      Console.WriteLine("After removing from both ends:");
      foreach (int item in deque) {
         Console.Write(item + " ");
      }
   }
}

The output of the above code is −

Deque contents:
5 10 20 30 
First element: 5
Last element: 30
After removing from both ends:
10 20 

Custom Deque Implementation

Here's a simple custom deque implementation using an internal doubly-linked list structure −

using System;
using System.Collections.Generic;

public class SimpleDeque<T> {
   private LinkedList<T> list = new LinkedList<T>();
   
   public void AddFirst(T item) {
      list.AddFirst(item);
   }
   
   public void AddLast(T item) {
      list.AddLast(item);
   }
   
   public T RemoveFirst() {
      if (list.Count == 0) throw new InvalidOperationException("Deque is empty");
      T value = list.First.Value;
      list.RemoveFirst();
      return value;
   }
   
   public T RemoveLast() {
      if (list.Count == 0) throw new InvalidOperationException("Deque is empty");
      T value = list.Last.Value;
      list.RemoveLast();
      return value;
   }
   
   public T PeekFirst() {
      if (list.Count == 0) throw new InvalidOperationException("Deque is empty");
      return list.First.Value;
   }
   
   public T PeekLast() {
      if (list.Count == 0) throw new InvalidOperationException("Deque is empty");
      return list.Last.Value;
   }
   
   public int Count => list.Count;
   public bool IsEmpty => list.Count == 0;
}

class Program {
   public static void Main() {
      SimpleDeque<string> deque = new SimpleDeque<string>();
      
      deque.AddFirst("Middle");
      deque.AddFirst("Front");
      deque.AddLast("Back");
      
      Console.WriteLine("Count: " + deque.Count);
      Console.WriteLine("First: " + deque.PeekFirst());
      Console.WriteLine("Last: " + deque.PeekLast());
      
      Console.WriteLine("Removed from front: " + deque.RemoveFirst());
      Console.WriteLine("Removed from back: " + deque.RemoveLast());
      Console.WriteLine("Remaining: " + deque.PeekFirst());
   }
}

The output of the above code is −

Count: 3
First: Front
Last: Back
Removed from front: Front
Removed from back: Back
Remaining: Middle

Common Use Cases

  • Sliding Window Algorithms ? efficiently add/remove elements from both ends

  • Browser History ? navigate forward and backward through pages

  • Undo/Redo Operations ? maintain operations that can be undone or redone

  • Job Scheduling ? add high-priority jobs to the front, regular jobs to the back

Conclusion

A deque provides flexible insertion and deletion from both ends, making it more versatile than standard queues or stacks. In C#, you can use LinkedList<T> directly or create a custom wrapper class to implement deque functionality for various algorithmic and data management scenarios.

Updated on: 2026-03-17T00:02:19+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements