
- 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.