How can I implement a queue using two stacks?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In data structures, a queue is an abstract data type that follows the First-In-First-Out (FIFO) principle. This means that the first element added to the queue will be the first one to be removed. On the other hand, a stack follows the Last-In-First-Out (LIFO) principle, where the last element added is the first to be removed.
Despite these differing behaviors, it's possible to implement a queue using two stacks. This can be particularly useful when working within constraints that require using stacks alone or when exploring different algorithm design patterns. In this article, we will explore how to implement a queue using two stacks.
Methodology
Components
To implement a queue using two stacks, you will need:
- Two stacks: We'll call them
Stack1andStack2.
Operations
For a queue, the essential operations are enqueue (adding an element) and dequeue (removing an element). Let's delve into implementing these operations using our two stacks.
Enqueue Operation
The enqueue operation is straightforward: simply push the element onto Stack1.
Pseudocode:
Dequeue Operation
The dequeue operation is where the logic becomes a bit more complex:
- If
Stack2is empty, pop all elements fromStack1and push them ontoStack2. - Pop the top element of
Stack2, which is the FIFO element for the queue.
This inversion of elements from Stack1 to Stack2 ensures that the first element added to the queue is at the top of Stack2.
Pseudocode:
Advantages and Trade-offs
Advantages
- Maintains FIFO Order: Even while using stacks (inherently LIFO), the queue maintains the FIFO ordering through element transfer.
Trade-offs
- Space Complexity: Two stacks are required, potentially doubling space usage.
- Time Complexity: In the worst case, a single
dequeueoperation can be more time-consuming since it involves transferring all elements fromStack1toStack2.
Time Complexity Analysis
| Operation | Average Time Complexity | Worst-case Time Complexity |
| Enqueue | ||
| Dequeue | (amortized) |
In the context of amortized time complexity, while a single dequeue can take up to time in the worst scenario (when all elements are shifted from Stack1 to Stack2), over a sequence of operations, the average time is ``$O(1)$`.
Example Implementation
Let's have a look at a simple implementation in Python:
Conclusion
This implementation leverages the characteristics of stacks to invert the order of insertion, effectively simulating the behavior of a queue. While it offers a clever demonstration of data structure manipulation, it's important to consider the trade-offs and understand the underlying mechanics thoroughly before employing this approach in production systems.

