Deque | Set 1 (Introduction and Applications)
Deque or Double Ended Queue is a generalized version of Queue data structure that allows insert and delete at both ends.
Operations on Deque: Below is a table showing some basic operations along with their time complexity, performed on deques.
Operation |
Description |
Time Complexity |
push_front() |
Inserts the element at the beginning. |
O(1) |
push_back() |
Adds element at the end. |
O(1) |
pop_front() |
Removes the first element from the deque. |
O(1) |
pop_back() |
Removes the last element from the deque. |
O(1) |
front() | Gets the front element from the deque. |
O(1) |
back() | Gets the last element from the deque. |
O(1) |
empty() | Checks whether the deque is empty or not. |
O(1) |
size() | Determines the number of elements in the deque. |
O(1) |
Other operations performed on deques are explained as follows:
clear(): Remove all the elements from the deque. It leaves the deque with a size of 0.
erase(): Remove one or more elements from the deque. It takes an iterator specifying the position of the first element to be removed, and an optional second iterator specifying the position of the last element to be removed.
swap(): Swap the contents of one deque with another deque.
emplace_front(): Insert a new element at the front of the deque. It is similar to the insert operation, but it avoids the copy constructor of the element being inserted.
emplace_back(): Insert a new element at the back of the deque. It is similar to the insert operation, but it avoids the copy constructor of the element being inserted.
resize(): Change the number of elements in the deque to a specific number. If the new size is larger than the current size, new elements are appended to the deque. If the new size is smaller than the current size, elements are removed from the deque.
assign(): Assign new values to the elements in the deque. It replaces the current contents of the deque with new elements.
reverse(): Reverse the order of the elements in the deque.
sort(): Sort the elements in the deque in ascending order. It uses the less-than operator to compare the elements.
Applications of Deque: Since Deque supports both stack and queue operations, it can be used as both. The Deque data structure supports clockwise and anticlockwise rotations in O(1) time which can be useful in certain applications. Also, the problems where elements need to be removed and or added to both ends can be efficiently solved using Deque. For example see the Maximum of all subarrays of size k problem., 0-1 BFS, and Find the first circular tour that visits all petrol pumps. See the wiki page for another example of the A-Steal job scheduling algorithm where Deque is used as deletions operation is required at both ends.
Some Practical Applications of Deque:
- Applied as both stack and queue, as it supports both operations.
- Storing a web browser’s history.
- Storing a software application’s list of undo operations.
- Job scheduling algorithm
Monotonic Deque :
- It is deque which stores elements in strictly increasing order or in strictly decreasing order
- To maintain monotonicity, we need to delete elements
- For example – Consider monotonic(decreasing) deque dq = {5, 4, 2, 1}
- Insert 3 into dq
- So we need to delete elements till dq.back() < 3 to insert 3 into dq (2,1 are the deleted elements)
- Resulting dq = {5, 4, 3}
- Applications of monotonic deque :
- It can be used to get next maximum in a subarray (sliding-window-maximum-of-all-subarrays-of-size-k) by using monotonically decreasing deque
- Like this it can be used to get previous maximum also in a subarray
- It is frequently used in sliding window problems (hard)
Other Applications:
Deques have several other applications, some of which include:
- Palindrome checking: Deques can be used to check if a word or phrase is a palindrome. By inserting each character of the word or phrase into a deque, it is possible to check if the word or phrase is a palindrome by comparing the first and last characters, the second and second-to-last characters, and so on.
- Graph traversal: Deques can be used to implement Breadth-First Search (BFS) on a graph. BFS uses a queue to keep track of the vertices to be visited next, and a deque can be used as an alternative to a queue in this case.
- Task scheduler: Deques can be used to implement a task scheduler that keeps track of tasks to be executed. Tasks can be added to the back of the deque, and the scheduler can remove tasks from the front of the deque and execute them.
- Multi-level undo/redo functionality: Deques can be used to implement undo and redo functionality in applications. Each time a user performs an action, the current state of the application is pushed onto the deque. When the user undoes an action, the front of the deque is popped, and the previous state is restored. When the user redoes an action, the next state is popped from the deque.
- In computer science, deque can be used in many algorithms like LRU Cache, Round Robin Scheduling, Expression Evaluation.
Language Support: C++ STL provides an implementation of Deque as std::deque and Java provides the Deque interface. See this for more details. Deque in Java Deque in Python
Implementation: A Deque can be implemented either using a doubly-linked list or a circular array. In both implementations, we can implement all operations in O(1) time. We will soon be discussing the C/C++ implementation of the Deque Data structure. Implementation of Deque using circular array Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem.
Contact Us