- DSA - Home
- DSA - Overview
- DSA - Environment Setup
- DSA - Algorithms Basics
- DSA - Asymptotic Analysis
- Data Structures
- DSA - Data Structure Basics
- DSA - Data Structures and Types
- DSA - Array Data Structure
- DSA - Skip List Data Structure
- Linked Lists
- DSA - Linked List Data Structure
- DSA - Doubly Linked List Data Structure
- DSA - Circular Linked List Data Structure
- Stack & Queue
- DSA - Stack Data Structure
- DSA - Expression Parsing
- DSA - Queue Data Structure
- DSA - Circular Queue Data Structure
- DSA - Priority Queue Data Structure
- DSA - Deque Data Structure
- Searching Algorithms
- DSA - Searching Algorithms
- DSA - Linear Search Algorithm
- DSA - Binary Search Algorithm
- DSA - Interpolation Search
- DSA - Jump Search Algorithm
- DSA - Exponential Search
- DSA - Fibonacci Search
- DSA - Sublist Search
- DSA - Hash Table
- Sorting Algorithms
- DSA - Sorting Algorithms
- DSA - Bubble Sort Algorithm
- DSA - Insertion Sort Algorithm
- DSA - Selection Sort Algorithm
- DSA - Merge Sort Algorithm
- DSA - Shell Sort Algorithm
- DSA - Heap Sort Algorithm
- DSA - Bucket Sort Algorithm
- DSA - Counting Sort Algorithm
- DSA - Radix Sort Algorithm
- DSA - Quick Sort Algorithm
- Matrices Data Structure
- DSA - Matrices Data Structure
- DSA - Lup Decomposition In Matrices
- DSA - Lu Decomposition In Matrices
- Graph Data Structure
- DSA - Graph Data Structure
- DSA - Depth First Traversal
- DSA - Breadth First Traversal
- DSA - Spanning Tree
- DSA - Topological Sorting
- DSA - Strongly Connected Components
- DSA - Biconnected Components
- DSA - Augmenting Path
- DSA - Network Flow Problems
- DSA - Flow Networks In Data Structures
- DSA - Edmonds Blossom Algorithm
- DSA - Maxflow Mincut Theorem
- Tree Data Structure
- DSA - Tree Data Structure
- DSA - Tree Traversal
- DSA - Binary Search Tree
- DSA - AVL Tree
- DSA - Red Black Trees
- DSA - B Trees
- DSA - B+ Trees
- DSA - Splay Trees
- DSA - Range Queries
- DSA - Segment Trees
- DSA - Fenwick Tree
- DSA - Fusion Tree
- DSA - Hashed Array Tree
- DSA - K-Ary Tree
- DSA - Kd Trees
- DSA - Priority Search Tree Data Structure
- Recursion
- DSA - Recursion Algorithms
- DSA - Tower of Hanoi Using Recursion
- DSA - Fibonacci Series Using Recursion
- Divide and Conquer
- DSA - Divide and Conquer
- DSA - Max-Min Problem
- DSA - Strassen's Matrix Multiplication
- DSA - Karatsuba Algorithm
- Greedy Algorithms
- DSA - Greedy Algorithms
- DSA - Travelling Salesman Problem (Greedy Approach)
- DSA - Prim's Minimal Spanning Tree
- DSA - Kruskal's Minimal Spanning Tree
- DSA - Dijkstra's Shortest Path Algorithm
- DSA - Map Colouring Algorithm
- DSA - Fractional Knapsack Problem
- DSA - Job Sequencing with Deadline
- DSA - Optimal Merge Pattern Algorithm
- Dynamic Programming
- DSA - Dynamic Programming
- DSA - Matrix Chain Multiplication
- DSA - Floyd Warshall Algorithm
- DSA - 0-1 Knapsack Problem
- DSA - Longest Common Sub-sequence Algorithm
- DSA - Travelling Salesman Problem (Dynamic Approach)
- Hashing
- DSA - Hashing Data Structure
- DSA - Collision In Hashing
- Disjoint Set
- DSA - Disjoint Set
- DSA - Path Compression And Union By Rank
- Heap
- DSA - Heap Data Structure
- DSA - Binary Heap
- DSA - Binomial Heap
- DSA - Fibonacci Heap
- Tries Data Structure
- DSA - Tries
- DSA - Standard Tries
- DSA - Compressed Tries
- DSA - Suffix Tries
- Treaps
- DSA - Treaps Data Structure
- Bit Mask
- DSA - Bit Mask In Data Structures
- Bloom Filter
- DSA - Bloom Filter Data Structure
- Approximation Algorithms
- DSA - Approximation Algorithms
- DSA - Vertex Cover Algorithm
- DSA - Set Cover Problem
- DSA - Travelling Salesman Problem (Approximation Approach)
- Randomized Algorithms
- DSA - Randomized Algorithms
- DSA - Randomized Quick Sort Algorithm
- DSA - Karger’s Minimum Cut Algorithm
- DSA - Fisher-Yates Shuffle Algorithm
- Miscellaneous
- DSA - Infix to Postfix
- DSA - Bellmon Ford Shortest Path
- DSA - Maximum Bipartite Matching
- DSA Useful Resources
- DSA - Questions and Answers
- DSA - Selection Sort Interview Questions
- DSA - Merge Sort Interview Questions
- DSA - Insertion Sort Interview Questions
- DSA - Heap Sort Interview Questions
- DSA - Bubble Sort Interview Questions
- DSA - Bucket Sort Interview Questions
- DSA - Radix Sort Interview Questions
- DSA - Cycle Sort Interview Questions
- DSA - Quick Guide
- DSA - Useful Resources
- DSA - Discussion
Deque Data Structure
Deque is a hybrid data structure that combines the features of a stack and a queue. It allows us to insert and delete elements from both ends of the queue. The name Deque is an abbreviation of Double-Ended Queue.
Imagine an event where you have two gates to enter and exit a place. People are entering from the front gate and some are entering from the side gate. Now, when people are leaving, they are leaving from the front gate and some sneak from the side gate. Now, we need to manage flow of people from both ends. This is where Deque comes into play.
Operations on Deque
Following are the major operations on Deque −
- push_front(x): Insert element x at the front of the deque.
- push_back(x): Insert element x at the back of the deque.
- pop_front(): Remove the element from the front of the deque.
- pop_back(): Remove the element from the back of the deque.
- peek_front(): Get the element from the front of the deque.
- peek_back(): Get the element from the back of the deque.
- size(): Get the number of elements in the deque.
- isEmpty(): Check if the deque is empty.
Implementation of Deque
Let's understand how we can implement deque using array. For this, we need to maintain two pointers, front and rear, to keep track of the front and back of the deque. We also need to define the size of the deque.
The push_front(x) Operation on Deque
When we insert an element at the front of the deque, we need to shift all the elements to the right by one position. We will increment the front pointer by one and insert the element at the front of the deque.
Algorithm for push_front(x)
Following are the steps to insert an element at the front of the deque −
1. Check if the deque is full. If it is full, return an error message. 2. Increment the front pointer by one. 3. Insert the element at the front position. 4. Increment the size of the deque.
implementation
Following is the implementation of push_front(x) operation on deque.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
int isFull() {
return (front == 0 && rear == SIZE - 1) || (front == rear + 1);
}
// Check if the deque is empty
int isEmpty() {
return front == -1;
}
// Insert element at the front
void push_front(int element) {
if (isFull()) {
printf("Deque is full\n");
return;
}
if (isEmpty()) { // First element being inserted
front = rear = 0;
} else {
// Circularly move front pointer
front = (front - 1 + SIZE) % SIZE;
}
deque[front] = element;
printf("Inserted -> %d\n", element);
}
// Display the deque
void display() {
if (isEmpty()) {
printf("Empty Deque\n");
return;
}
int i = front;
printf("Elements -> ");
while (1) {
printf("%d ", deque[i]);
if (i == rear) break; // Stop at the last element
i = (i + 1) % SIZE; // Circular increment
}
printf("\n");
}
int main() {
push_front(1);
push_front(2);
push_front(3);
push_front(4);
push_front(5);
display();
return 0;
}
Output
The output obtained is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 5 4 3 2 1
#include <iostream>
using namespace std;
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
bool isFull() {
return (front == 0 && rear == SIZE - 1) || (front == rear + 1);
}
// Check if the deque is empty
bool isEmpty() {
return front == -1;
}
// Insert element at the front
void push_front(int element) {
if (isFull()) {
cout << "Deque is full" << endl;
return;
}
if (isEmpty()) { // First element being inserted
front = rear = 0;
}
else if (front == 0) { // Wrap around
front = SIZE - 1;
}
else {
front--;
}
deque[front] = element;
cout << "Inserted -> " << element << endl;
}
// Display the deque
void display() {
if (isEmpty()) {
cout << "Empty Deque" << endl;
return;
}
cout << "Elements -> ";
int i = front;
while (true) {
cout << deque[i] << " ";
if (i == rear) break; // Stop at last element
i = (i + 1) % SIZE; // Circular increment
}
cout << endl;
}
int main() {
push_front(1);
push_front(2);
push_front(3);
push_front(4);
push_front(5);
display();
return 0;
}
Output
The output produced is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 5 4 3 2 1
//Java Program
class Deque {
static final int SIZE = 5;
static int deque[] = new int[SIZE];
static int front = -1, rear = -1;
// Check if the deque is full
static boolean isFull() {
return (front == 0 && rear == SIZE - 1) || (front == rear + 1);
}
// Check if the deque is empty
static boolean isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the front
static void push_front(int element) {
if (isFull()) System.out.println("Deque is full");
if(isEmpty()) {
front = rear = 0;
}else {
front = (front - 1 + SIZE) % SIZE;
}
deque[front] = element;
System.out.println("Inserted -> " + element);
}
// Display the deque
static void display() {
if (isEmpty()) System.out.println("Empty Deque");
System.out.print("Elements -> ");
int i = front;
while (true) {
System.out.print(deque[i] + " ");
if (i == rear) break;
i = (i + 1) % SIZE;
}
System.out.println();
}
}
public class Main{
public static void main(String[] args) {
Deque deque = new Deque();
deque.push_front(1);
deque.push_front(2);
deque.push_front(3);
deque.push_front(4);
deque.push_front(5);
deque.display();
}
}
Output
The output is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 5 4 3 2 1
SIZE = 5
deque = [0] * SIZE
front = -1
rear = -1
# Check if the deque is full
def isFull():
return (front == 0 and rear == SIZE - 1) or (front == rear + 1)
# Check if the deque is empty
def isEmpty():
return front == -1
# Insert element at the front
def push_front(element):
global front, rear
if isFull():
print("Deque is full")
if isEmpty():
front = rear = 0
else:
front = (front - 1 + SIZE) % SIZE
deque[front] = element
print("Inserted ->", element)
# Display the deque
def display():
global front, rear
if isEmpty():
print("Empty Deque")
else:
i = front
print("Elements ->", end=" ")
while i != rear:
print(deque[i], end=" ")
i = (i + 1) % SIZE
print(deque[rear]) # Print the last element
# Testing the functions
push_front(1)
push_front(2)
push_front(3)
push_front(4)
push_front(5)
display()
Output
Following is the output of the above code −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 5 4 3 2 1
push_back(x) Operation
This operation is used for inserting an element to the back of the deque. When we insert an element at the back of the deque, we need to increment the rear pointer by one and insert the element at the back of the deque.
Algorithm for push_back(x)
Following are the steps to insert an element at the back of the deque −
1. Check if the deque is full. 2. Increment the rear pointer by one. 3. Insert the element at the rear position. 4. Increment the size of the deque.
Implementation
Following is the implementation of push_back(x) operation on deque.
//C Program
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
int isFull() {
return ((front == 0 && rear == SIZE - 1) || (front == rear + 1));
}
// Check if the deque is empty
int isEmpty() {
return (front == -1);
}
// Insert element at the back
void push_back(int element) {
if (isFull()) {
printf("Deque is full\n");
} else {
if (front == -1) { // If deque is initially empty
front = rear = 0;
} else if (rear == SIZE - 1) { // Wrap around to the front
rear = 0;
} else {
rear++;
}
deque[rear] = element;
printf("Inserted -> %d\n", element);
}
}
// Display the deque
void display() {
if (isEmpty()) {
printf("Empty Deque\n");
} else {
printf("Elements -> ");
int i = front;
while (1) {
printf("%d ", deque[i]);
if (i == rear) break; // Stop when the rear is reached
i = (i + 1) % SIZE; // Circular increment
}
printf("\n");
}
}
// Main function
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
display();
return 0;
}
Output
The output obtained is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 1 2 3 4 5
#include <iostream>
using namespace std;
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
bool isFull() {
return (front == 0 && rear == SIZE - 1) || (front == rear + 1);
}
// Check if the deque is empty
bool isEmpty() {
return front == -1;
}
// Insert element at the back
void push_back(int element) {
if (isFull()) {
cout << "Deque is full" << endl;
} else {
if (front == -1) { // First insertion
front = 0;
rear = 0;
} else if (rear == SIZE - 1 && front != 0) { // Wrap around
rear = 0;
} else { // Normal case
rear++;
}
deque[rear] = element;
cout << "Inserted -> " << element << endl;
}
}
// Display the deque
void display() {
if (isEmpty()) {
cout << "Empty Deque" << endl;
} else {
cout << "Elements -> ";
int i = front;
while (true) {
cout << deque[i] << " ";
if (i == rear) break; // Stop when the last element is printed
i = (i + 1) % SIZE; // Move circularly
}
cout << endl;
}
}
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
display();
return 0;
}
Output
The output produced is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 1 2 3 4 5
//Java Program
class Deque {
static final int SIZE = 5;
static int deque[] = new int[SIZE];
static int front = -1, rear = -1;
// Check if the deque is full
static boolean isFull() {
if ((front == 0 && rear == SIZE - 1) || front == rear + 1) return true;
return false;
}
// Check if the deque is empty
static boolean isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the back
static void push_back(int element) {
if (isFull()) System.out.println("Deque is full");
else {
if (front == -1) front = 0;
if (rear == SIZE - 1) rear = 0;
else rear = rear + 1;
deque[rear] = element;
System.out.println("Inserted -> " + element);
}
}
// Display the deque
static void display() {
int i = front;
if (isEmpty()) System.out.println("Empty Deque");
else {
System.out.print("Elements -> ");
for (i = front; i != rear; i = (i + 1) % SIZE) {
System.out.print(deque[i] + " ");
}
System.out.print(deque[i]);
}
}
}
public class Main{
public static void main(String[] args) {
Deque deque = new Deque();
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
deque.push_back(4);
deque.push_back(5);
deque.display();
}
}
Output
The output is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 1 2 3 4 5
#Python Program
SIZE = 5
deque = [0] * SIZE
front = -1
rear = -1
# Check if the deque is full
def isFull():
if (front == 0 and rear == SIZE - 1) or (front == rear + 1):
return True
return False
# Check if the deque is empty
def isEmpty():
if front == -1:
return True
return False
# Insert element at the back
def push_back(element):
global front, rear
if isFull():
print("Deque is full")
else:
if front == -1: # Initial insertion
front = 0
rear = 0
elif rear == SIZE - 1 and front != 0: # Wrap around
rear = 0
else: # Normal case
rear += 1
deque[rear] = element
print("Inserted ->", element)
# Display the deque
def display():
global front, rear
if isEmpty():
print("Empty Deque")
else:
print("Elements ->", end=" ")
i = front
while True:
print(deque[i], end=" ")
if i == rear: # Stop when we reach the last element
break
i = (i + 1) % SIZE # Move to the next index, circularly
print()
# Test the deque
push_back(1)
push_back(2)
push_back(3)
push_back(4)
push_back(5)
display()
Output
Following is the output of the above code −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Elements -> 1 2 3 4 5
The pop_front() and pop_back() Operations on Deque
These operation is done when we need to remove elements from front or back. When we remove an element from the front of the deque, we need to increment the front pointer by one.
Similarly, when we remove an element from the back of the deque, we need to decrement the rear pointer by one.
Algorithm for pop_front() and pop_back()
Following are the steps to remove an element from the front or back of the deque −
1. Check if the deque is empty. 2. Remove the element from the front or back of the deque. 3. Increment or decrement the front or rear pointer. 4. Decrement the size of the deque.
Implementation
Following is the implementation of pop_front() and pop_back() operations on deque.
//C Program
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
int isFull() {
return ((front == 0 && rear == SIZE - 1) || (front == rear + 1));
}
// Check if the deque is empty
int isEmpty() {
return (front == -1);
}
// Insert element at the back
void push_back(int element) {
if (isFull()) {
printf("Deque is full\n");
} else {
if (front == -1) { // If deque is initially empty
front = rear = 0;
} else if (rear == SIZE - 1) { // Wrap around to the front
rear = 0;
} else {
rear++;
}
deque[rear] = element;
printf("Inserted -> %d\n", element);
}
}
// Remove element from the front
void pop_front() {
if (isEmpty()) {
printf("Deque is empty\n");
} else {
printf("Deleted from front -> %d\n", deque[front]);
if (front == rear) { // If only one element is present
front = rear = -1;
} else {
front = (front + 1) % SIZE;
}
}
}
// Remove element from the back
void pop_back() {
if (isEmpty()) {
printf("Deque is empty\n");
} else {
printf("Deleted from back -> %d\n", deque[rear]);
if (front == rear) { // If only one element is present
front = rear = -1;
} else if (rear == 0) {
rear = SIZE - 1;
} else {
rear--;
}
}
}
// Display the deque
void display() {
if (isEmpty()) {
printf("Empty Deque\n");
} else {
printf("Elements -> ");
int i = front;
while (1) {
printf("%d ", deque[i]);
if (i == rear) break; // Stop when the rear is reached
i = (i + 1) % SIZE; // Circular increment
}
printf("\n");
}
}
// Main function
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
pop_front();
pop_back();
display();
return 0;
}
Output
The output obtained is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Deleted -> 1 Deleted -> 5
//C++ Program
#include <iostream>
using namespace std;
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
bool isFull() {
if ((front == 0 && rear == SIZE - 1) || front == rear + 1) return true;
return false;
}
// Check if the deque is empty
bool isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the back
void push_back(int element) {
if (isFull()) cout << "Deque is full" << endl;
else {
if (front == -1) front = 0;
if (rear == SIZE - 1) rear = 0;
else rear = rear + 1;
deque[rear] = element;
cout << "Inserted -> " << element << endl;
}
}
// Remove element from the front
void pop_front() {
if (isEmpty()) cout << "Deque is empty" << endl;
else {
cout << "Deleted from front -> " << deque[front] << endl;
if (front == rear) front = rear = -1;
else front = (front + 1) % SIZE;
}
}
// Remove element from the back
void pop_back() {
if (isEmpty()) cout << "Deque is empty" << endl;
else {
cout << "Deleted from back -> " << deque[rear] << endl;
if (front == rear) front = rear = -1;
else if (rear == 0) rear = SIZE - 1;
else rear = rear - 1;
}
}
// Display the deque
void display() {
int i = front;
if (isEmpty()) cout << "Empty Deque" << endl;
else {
cout << "Elements -> ";
for (int i = front; i != rear; i = (i + 1) % SIZE) {
cout << deque[i] << " ";
}
cout << deque[i];
}
}
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
pop_front();
pop_back();
display();
return 0;
}
Output
The output produced is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Deleted from front -> 1 Deleted from back -> 5 Elements -> 2 3 4
//Java Program
class Deque {
static final int SIZE = 5;
static int deque[] = new int[SIZE];
static int front = -1, rear = -1;
// Check if the deque is full
static boolean isFull() {
if ((front == 0 && rear == SIZE - 1) || front == rear + 1) return true;
return false;
}
// Check if the deque is empty
static boolean isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the back
static void push_back(int element) {
if (isFull()) System.out.println("Deque is full");
else {
if (front == -1) front = 0;
if (rear == SIZE - 1) rear = 0;
else rear = rear + 1;
deque[rear] = element;
System.out.println("Inserted -> " + element);
}
}
// Remove element from the front
static void pop_front() {
if (isEmpty()) System.out.println("Deque is empty");
else {
System.out.println("Deleted from front -> " + deque[front]);
if (front == rear) front = rear = -1;
else front = (front + 1) % SIZE;
}
}
// Remove element from the back
static void pop_back() {
if (isEmpty()) System.out.println("Deque is empty");
else {
System.out.println("Deleted from back -> " + deque[rear]);
if (front == rear) front = rear = -1;
else if (rear == 0) rear = SIZE - 1;
else rear = rear - 1;
}
}
// Display the deque
static void display() {
int i = front;
if (isEmpty()) System.out.println("Empty Deque");
else {
System.out.print("Elements -> ");
for (i = front; i != rear; i = (i + 1) % SIZE) {
System.out.print(deque[i] + " ");
}
System.out.print(deque[i]);
}
}
}
public class Main{
public static void main(String[] args) {
Deque deque = new Deque();
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
deque.push_back(4);
deque.push_back(5);
deque.pop_front();
deque.pop_back();
deque.display();
}
}
Output
The output is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Deleted from front -> 1 Deleted from back -> 5 Elements -> 2 3 4
#Python Program
SIZE = 5
deque = [0] * SIZE
front = -1
rear = -1
# Check if the deque is full
def isFull():
if (front == 0 and rear == SIZE - 1) or front == rear + 1: return True
return False
# Check if the deque is empty
def isEmpty():
if front == -1: return True
return False
# Insert element at the back
def push_back(element):
global front
global rear
if isFull(): print("Deque is full")
else:
if front == -1: front = 0
if rear == SIZE - 1: rear = 0
else: rear = rear + 1
deque[rear] = element
print("Inserted ->", element)
# Remove element from the front
def pop_front():
global front
global rear
if isEmpty(): print("Deque is empty")
else:
print("Deleted from front ->", deque[front])
if front == rear: front = rear = -1
else: front = (front + 1) % SIZE
# Remove element from the back
def pop_back():
global front
global rear
if isEmpty(): print("Deque is empty")
else:
print("Deleted from back ->", deque[rear])
if front == rear: front = rear = -1
elif rear == 0: rear = SIZE - 1
else: rear = rear - 1
# Display the deque
def display():
i = front
if isEmpty(): print("Empty Deque")
else:
print("Elements ->", end = " ")
while True:
print(deque[i], end = " ")
if i == rear: break
i = (i + 1) % SIZE
print(deque[rear])
push_back(1)
push_back(2)
push_back(3)
push_back(4)
push_back(5)
pop_front()
pop_back()
display()
Output
Following is the output of the above code −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Deleted from front -> 1 Deleted from back -> 5 Elements -> 2 3 4
The peek_front() and peek_back() Operations on Deque
When we want to get the element from the front or back of the deque, we can use the peek_front() and peek_back() operations.
Algorithm for peek_front() and peek_back()
Following are the steps to get the element from the front or back of the deque −
1. Check if the deque is empty. 2. If not empty, return the element from the front or back of the deque.
Implementation
Following is the implementation code of peek_front() and peek_back() operations on deque.
//C Program
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
int isFull() {
return ((front == 0 && rear == SIZE - 1) || (front == rear + 1));
}
// Check if the deque is empty
int isEmpty() {
return (front == -1);
}
// Insert element at the back
void push_back(int element) {
if (isFull()) {
printf("Deque is full\n");
} else {
if (front == -1) { // If deque is initially empty
front = rear = 0;
} else if (rear == SIZE - 1) { // Wrap around to the front
rear = 0;
} else {
rear++;
}
deque[rear] = element;
printf("Inserted -> %d\n", element);
}
}
// Get the element from the front
int peek_front() {
if (isEmpty()) {
printf("Deque is empty\n");
return -1;
} else {
return deque[front];
}
}
// Get the element from the back
int peek_back() {
if (isEmpty()) {
printf("Deque is empty\n");
return -1;
} else {
return deque[rear];
}
}
// Main function
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
printf("\nElement at front: %d\n", peek_front());
printf("Element at back: %d\n", peek_back());
return 0;
}
Output
The output obtained is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Element at front: 1 Element at back: 5
//C++ Program
#include <iostream>
using namespace std;
#define SIZE 5
int deque[SIZE];
int front = -1, rear = -1;
// Check if the deque is full
bool isFull() {
if ((front == 0 && rear == SIZE - 1) || front == rear + 1) return true;
return false;
}
// Check if the deque is empty
bool isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the back
void push_back(int element) {
if (isFull()) cout << "Deque is full" << endl;
else {
if (front == -1) front = 0;
if (rear == SIZE - 1) rear = 0;
else rear = rear + 1;
deque[rear] = element;
cout << "Inserted -> " << element << endl;
}
}
// Get the element from the front
int peek_front() {
if (isEmpty()) {
cout << "Deque is empty" << endl;
return -1;
} else {
return deque[front];
}
}
// Get the element from the back
int peek_back() {
if (isEmpty()) {
cout << "Deque is empty" << endl;
return -1;
} else {
return deque[rear];
}
}
int main() {
push_back(1);
push_back(2);
push_back(3);
push_back(4);
push_back(5);
cout << "\nElement at front: " << peek_front() << endl;
cout << "Element at back: " << peek_back() << endl;
return 0;
}
Output
The output produced is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Element at front: 1 Element at back: 5
//Java Program
class PeekFrontAndBack{
static final int SIZE = 5;
static int deque[] = new int[SIZE];
static int front = -1, rear = -1;
// Check if the deque is full
static boolean isFull() {
if ((front == 0 && rear == SIZE - 1) || front == rear + 1) return true;
return false;
}
// Check if the deque is empty
static boolean isEmpty() {
if (front == -1) return true;
return false;
}
// Insert element at the back
static void push_back(int element) {
if (isFull()) System.out.println("Deque is full");
else {
if (front == -1) front = 0;
if (rear == SIZE - 1) rear = 0;
else rear = rear + 1;
deque[rear] = element;
System.out.println("Inserted -> " + element);
}
}
// Get the element from the front
static int peek_front() {
if (isEmpty()) {
System.out.println("Deque is empty");
return -1;
} else {
return deque[front];
}
}
// Get the element from the back
static int peek_back() {
if (isEmpty()) {
System.out.println("Deque is empty");
return -1;
} else {
return deque[rear];
}
}
}
public class Main{
public static void main(String[] args) {
PeekFrontAndBack deque = new PeekFrontAndBack();
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
deque.push_back(4);
deque.push_back(5);
System.out.println("\nElement at front: " + deque.peek_front());
System.out.println("Element at back: " + deque.peek_back());
}
}
Output
The output is as follows −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Element at front: 1 Element at back: 5
#Python Program
SIZE = 5
deque = [0] * SIZE
front = -1
rear = -1
# Check if the deque is full
def isFull():
if (front == 0 and rear == SIZE - 1) or front == rear + 1: return True
return False
# Check if the deque is empty
def isEmpty():
if front == -1: return True
return False
# Insert element at the back
def push_back(element):
global front
global rear
if isFull(): print("Deque is full")
else:
if front == -1: front = 0
if rear == SIZE - 1: rear = 0
else: rear = rear + 1
deque[rear] = element
print("Inserted ->", element)
# Get the element from the front
def peek_front():
if isEmpty():
print("Deque is empty")
return -1
else:
return deque[front]
# Get the element from the back
def peek_back():
if isEmpty():
print("Deque is empty")
return -1
else:
return deque[rear]
push_back(1)
push_back(2)
push_back(3)
push_back(4)
push_back(5)
print("\nElement at front:", peek_front())
print("Element at back:", peek_back())
Output
Following is the output of the above code −
Inserted -> 1 Inserted -> 2 Inserted -> 3 Inserted -> 4 Inserted -> 5 Element at front: 1 Element at back: 5
Time Complexity of Deque Operations
The time complexity of the deque operations is as follows −
- push_front(x) − O(1)
- push_back(x) − O(1)
- pop_front() − O(1)
- pop_back() − O(1)
- peek_front() − O(1)
- peek_back() − O(1)
Thus, the deque operations have a time complexity of O(1).
Applications of Deque
Some of the applications of deque are as follows −
- Deque is used for undo operation in text editors.
- It is also used in implementation of the sliding window algorithm.
- Deque is used in implementing the data structures like double-ended priority queue and double-ended stack.
In summary, we use deque when we need to perform insertion and deletion operations at both ends of the data structure.