Queues are a fundamental data structure that follow the First-In-First-Out (FIFO) principle. This principle is exactly opposite of Last-In-First-Out (LIFO) principle on which Stack data structure is based on. While queues can be implemented directly using an array or a linked list, they can also be constructed using two stacks.
Implementing a queue with stacks involves maintaining two stacks, where one stack is used to store the elements, while the other stack is used to reverse the order of the elements. Reversing the order of elements in the stack makes sure that among all the elements present in the stack, the most oldest or first element added to the stack will always stay on top of the stack. Similarly the next oldest element is the next topmost element in the stack and so on. The recently added element should be at the bottom of the stack. This ensures that the first element added will be the first element to be popped out, similar to how the Queue behaves.
Below is a basic program which demonstrates implementing a queue data structure using two stack objects:
Here’s how the implementation works:
- The
Queueclass has two stacks:stack1andstack2. - In the
enqueueoperation:- We ensure that the topmost element in the stack is always the first element added to the Queue among all the elements present.
- And bottom most element in the stack should the mostly recently added element.
- In order to achieve this, we perform the below steps:
- Move all elements from
stack1tostack2. - Push the new item to
stack1. - Move all elements back from
stack2tostack1. - The time complexity is O(N), where N is the number of elements in the queue.
- Move all elements from
- The
dequeueoperation:- Checks if the
stack1is empty. If it is, it raises an error indicating that the queue is empty. - Otherwise, it pops the top element from
stack1, which is the first element added to the queue. - The time complexity of the
dequeueoperation is O(1).
- Checks if the
- The
peekoperation:- Checks if the
stack1is empty. If it is, it raises an error indicating that the queue is empty. - Otherwise, it returns the top element of
stack1, which is the first element added to the queue. - The time complexity of the
peekoperation is O(1).
- Checks if the
- The
is_emptyoperation:- Returns
Trueifstack1is empty, indicating that the queue is empty. - The time complexity of the
is_emptyoperation is O(1).
- Returns
This implementation ensures that the enqueue operation takes O(N) time, while the dequeue, peek, and is_empty operations take O(1) time. There are other variations of implementations as well with different time complexities. This implementation is simpler to understand among all as the core logic of reversing the order of elements in the stack is done only in one operation enqueue.