C++ Deque
Understanding double-ended queue containers
๐ What is C++ Deque?
C++ Deque (double-ended queue) allows fast insertion and deletion at both ends. It combines benefits of vectors and lists, providing random access with efficient front/back operations.
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> myDeque = {2, 3, 4};
myDeque.push_front(1);
myDeque.push_back(5);
for(int num : myDeque) {
cout << num << " ";
}
return 0;
}
Output:
1 2 3 4 5
Key Deque Operations
Front Operations
Add/remove elements at the beginning
myDeque.push_front(10);
myDeque.pop_front();
Back Operations
Add/remove elements at the end
myDeque.push_back(20);
myDeque.pop_back();
Random Access
Access elements by index like arrays
cout << myDeque[0];
myDeque.at(1) = 100;
Size Operations
Check size and capacity
cout << myDeque.size();
cout << myDeque.empty();
๐น Basic Deque Operations
A deque (double-ended queue) supports fast insertion and deletion at both its front and back. You
can use push_front(), push_back(), pop_front(), and pop_back()
to modify ends efficiently. Unlike vectors, deques donโt guarantee contiguous storage but offer constant-time front
operations. They are ideal for scenarios requiring a sliding window, queues, or stacks where elements are frequently
added or removed from both ends.
#include <iostream>
#include <deque>
using namespace std;
int main() {
// Create a deque
deque<int> numbers;
// Add elements at both ends
numbers.push_back(30);
numbers.push_back(40);
numbers.push_front(20);
numbers.push_front(10);
// Display deque
cout << "Deque: ";
for(int i = 0; i < numbers.size(); i++) {
cout << numbers[i] << " ";
}
cout << endl;
// Access first and last elements
cout << "First: " << numbers.front() << endl;
cout << "Last: " << numbers.back() << endl;
return 0;
}
Output:
Deque: 10 20 30 40
First: 10
Last: 40
๐น Deque Insertion and Deletion
Deques provide efficient methods for inserting and erasing elements at either end or in the middle.
While front/back operations are O(1), insertions in the middle are linear time. Functions like insert()
and erase() work with iterators for precise positioning. For example, you can add a color to the front,
remove one from the back, or insert an element at a specific index. This flexibility makes deques versatile for
dynamic sequences.
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<string> colors = {"red", "green", "blue"};
// Add at front and back
colors.push_front("yellow");
colors.push_back("purple");
cout << "After adding: ";
for(const string& color : colors) {
cout << color << " ";
}
cout << endl;
// Remove from front and back
colors.pop_front();
colors.pop_back();
cout << "After removing: ";
for(const string& color : colors) {
cout << color << " ";
}
cout << endl;
// Insert at specific position
colors.insert(colors.begin() + 1, "orange");
cout << "After insert: ";
for(const string& color : colors) {
cout << color << " ";
}
return 0;
}
Output:
After adding: yellow red green blue purple
After removing: red green blue
After insert: red orange green blue
๐น Deque vs Vector vs List
Choosing between deque, vector, and list depends on your access patterns and modification needs.
Vectors provide O(1) random access and maintain contiguous memory, making them ideal for frequent index-based
lookups, but suffer from slow front insertions and deletions. Deques offer efficient O(1) operations at both ends
while supporting fast random access, though they don't guarantee contiguous storage. Lists excel at constant-time
insertions and deletions anywhere in the sequence but lack random access capability, requiring iterators for
traversal. Select std::vector for predominantly sequential or back-end operations,
std::deque when you need fast front and
back modifications, and std::list for frequent middle insertions or deletions to optimize performance
and memory usage
in your applications.
#include <iostream>
#include <deque>
#include <vector>
#include <chrono>
using namespace std;
int main() {
deque<int> myDeque;
vector<int> myVector;
// Deque: Fast front insertion
auto start = chrono::high_resolution_clock::now();
for(int i = 0; i < 1000; i++) {
myDeque.push_front(i);
}
auto end = chrono::high_resolution_clock::now();
cout << "Deque front insertion: Fast" << endl;
// Vector: Slow front insertion (needs shifting)
start = chrono::high_resolution_clock::now();
for(int i = 0; i < 1000; i++) {
myVector.insert(myVector.begin(), i);
}
end = chrono::high_resolution_clock::now();
cout << "Vector front insertion: Slow" << endl;
// Both support random access
cout << "Deque[500]: " << myDeque[500] << endl;
cout << "Vector[500]: " << myVector[500] << endl;
return 0;
}
Output:
Deque front insertion: Fast
Vector front insertion: Slow
Deque[500]: 499
Vector[500]: 499