Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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 frontAddLast()? adds an element to the backRemoveFirst()? removes an element from the frontRemoveLast()? removes an element from the backPeekFirst()? views the front element without removing itPeekLast()? views the back element without removing it
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.
