A double-ended queue (commonly written deque or double-ended queue) is a linear data structure that allows insertion and removal of elements from both ends - the front and the back. It generalises both stacks and queues: a deque supports push and pop operations at both ends. Deques are used where flexibility of both LIFO and FIFO behaviour is required.

One common implementation of a deque uses a circular array. The circular array lets front and rear indices wrap around when they reach the array boundaries, enabling efficient use of fixed array space. The implementation below provides the typical operations supported by a deque.
The following C++ style outline shows a circular-array implementation with a fixed maximum size.
#define SIZE 5
class Dequeue {
int *arr;
int front, rear;
public:
Dequeue() {
arr = new int[SIZE];
front = -1;
rear = -1;
}
void push_front(int key);
void push_back(int key);
void pop_front();
void pop_back();
int get_front();
int get_back();
bool full();
bool empty();
};
Before inserting, check whether the deque is full. If not full, insert at the front using circular behaviour for the index.


void Dequeue::push_front(int key) {
if (full()) {
std::cout <>
";="" }="" else="" {="" if="" (front="=" -1)="" empty="" deque="" front="rear" =="" 0;="" else="" if="" (front="=" 0)="" wrap="" front="" to="" end="" front="SIZE" -="" 1;="" else="" --front;="" arr[front]="key;" }="" }="">
Before inserting, check whether the deque is full. If not full, insert at the rear using circular index updates.

void Dequeue::push_back(int key) {
if (full()) {
std::cout <>
";="" }="" else="" {="" if="" (front="=" -1)="" empty="" deque="" front="rear" =="" 0;="" else="" if="" (rear="=" size="" -="" 1)="" wrap="" rear="" to="" start="" rear="0;" else="" ++rear;="" arr[rear]="key;" }="" }="">
To remove the element at the front, first check if the deque is empty. If not empty, remove and update indices according to these rules.

void Dequeue::pop_front() {
if (empty()) {
std::cout <>
";="" }="" else="" {="" if="" (front="=" rear)="" only="" one="" element="" front="rear" =="" -1;="" else="" if="" (front="=" size="" -="" 1)="" wrap="" front="" to="" start="" front="0;" else="" ++front;="" }="" }="">
To remove the element at the rear, first check if the deque is empty. If not empty, remove and update indices according to these rules.

void Dequeue::pop_back() {
if (empty()) {
std::cout <>
";="" }="" else="" {="" if="" (front="=" rear)="" only="" one="" element="" front="rear" =="" -1;="" else="" if="" (rear="=" 0)="" wrap="" rear="" to="" end="" rear="SIZE" -="" 1;="" else="" --rear;="" }="" }="">
A deque implemented with the above convention is empty when front == -1.
bool Dequeue::empty() {
if (front == -1)
return true;
else
return false;
}
For a circular array, the deque is full when the next position of rear is front. The common tests are shown below.
bool Dequeue::full() {
if ((front == 0 && rear == SIZE - 1) || (front == rear + 1))
return true;
else
return false;
}
If the deque is not empty, return the value at arr[front]. If it is empty, indicate underflow or return a sentinel value (for example -1) as a simple error signal.
int Dequeue::get_front() {
if (empty()) {
std::cout <>
";="" return="" -1;="" }="" else="" {="" return="" arr[front];="" }="" }="">
If the deque is not empty, return the value at arr[rear]. If it is empty, indicate underflow or return a sentinel value.
int Dequeue::get_back() {
if (empty()) {
std::cout <>
";="" return="" -1;="" }="" else="" {="" return="" arr[rear];="" }="" }="">
Deques can also be implemented using a doubly linked list. In a doubly linked list:
Consider an initially empty deque with SIZE = 5 and the following sequence of operations:
Trace of front, rear and array contents after each operation:
This example demonstrates the wrap-around of indices and how the logical order differs from physical positions in the array.
A deque is a flexible linear structure that permits insertion and deletion at both ends in constant time. The circular-array implementation is efficient when an upper bound on size is known, while a doubly linked list provides dynamic sizing. Understanding index updates (wrap-around) and careful handling of empty/full states are essential for a correct implementation.
| 1. What is a Double Ended Queue (Deque)? | ![]() |
| 2. What are the basic operations supported by a Double Ended Queue? | ![]() |
| 3. How is a Double Ended Queue different from a regular queue? | ![]() |
| 4. What are the advantages of using a Double Ended Queue? | ![]() |
| 5. In what scenarios is a Double Ended Queue useful? | ![]() |
|
Explore Courses for Computer Science Engineering (CSE) exam
|
|
|
Get EduRev Notes directly in your Google search
|
|