blog bg

June 17, 2025

Implementing a Stack Using Queues: A Creative Approach

Share what you learn in this blog to prepare for your interview, create your forever-free profile now, and explore how to monetize your valuable knowledge.

 

Stacks are usually associated with Last In, First Out (LIFO) behavior. You have probably used a stack to reverse a text, check for balanced parentheses, or track function calls. So what if I told you that queues can implement a stack? A First In, First Out (FIFO) queue. It seems paradoxical, no? In this tutorial, we will utilize queues to replicate stack behavior creatively. This is more fun than it sounds. 

 

Understanding the Stack and Queue Data Structures 

First, let's review stacks and queues to understand the difficulty. A stack is a pile where the last thing added is the first removed. It is like a stack of plates: the last one added is the first one taken away. 

Like a coffee shop line, a queue serves the first person in line. FIFO places removal in the opposite order of entry. Imagine leveraging a queue's FIFO behavior to implement the stack's LIFO. The issue is difficult, but we will tackle it. 

 

Approach 1: Using Two Queues to Implement a Stack 

Using two queues to implement a stack is easiest. The core idea: The first queue will hold the stack items, while the second will reverse the order of insertion when we push new elements. 

Here's how it works:

  • When we add an item to the stack, we first put it in the second queue. Next, we shift all the items from the first queue to the second queue, placing the new item at the front.
  • Popping an element dequeues it from the first queue. Since we put the elements in reverse order during the push process, the latest element will always be at the front of the first list.

Let's examine the code for this approach:

 

from queue import Queue

class StackUsingQueues:
    def __init__(self):
        self.q1 = Queue()
        self.q2 = Queue()

    def push(self, x):
        self.q2.put(x)
        while not self.q1.empty():
           self.q2.put(self.q1.get())
        self.q1, self.q2 = self.q2, self.q1

    def pop(self):
        if not self.q1.empty():
            return self.q1.get()
        return None

# Example usage
stack = StackUsingQueues()
stack.push(10)
stack.push(20)
stack.push(30)
print(stack.pop())  # Outputs 30

We temporarily transfer everything from q1 to q2 and insert the new element at the front when we push it in this code. As in a stack, popping removes the most recently inserted item first. 

 

Approach 2: Using Two Queues for More Efficient Stack Operations 

Although the first approach works, it is not the most effective for popping components. In the previous implementation, pushing an element moved all items from one queue to another. This may be inefficient for many push operations. So, the answer? 

Two queues and optimized pop operations make this stack implementation more efficient. Only move parts during the pop process, not each push. 

Here's how it works:

  • When we add an item, we just place it in the first queue. 
  • When we remove an item, we move all the items from the first queue to the second queue, except for the last one. We need to remove the last thing from the first queue because it is the newest one added. 
  • After we pop an item, we switch the two queues so that the first queue is ready for the next action.

Here's how this looks in code:

 

from queue import Queue

class StackUsingQueuesEfficient:
    def __init__(self):
        self.q1 = Queue()
        self.q2 = Queue()

    def push(self, x):
        self.q1.put(x)

    def pop(self):
        if self.q1.empty():
            return None
        while self.q1.qsize() > 1:
           self.q2.put(self.q1.get())
        popped_element = self.q1.get()
        self.q1, self.q2 = self.q2, self.q1
        return popped_element

# Example usage
stack = StackUsingQueuesEfficient()
stack.push(10)
stack.push(20)
stack.push(30)
print(stack.pop())  # Outputs 30

We decrease push operations in our second approach. We prioritize popping items, the important stack operation. 

 

Conclusion

Both approaches allow us to create a stack using queues, but each has drawbacks. The first approach is simpler and easy to apply but less efficient for numerous push operations. The second approach maximizes pop efficiency but involves queue management. 

They should have shown you how to utilize various data structures creatively to solve issues. Implementing a stack with queues lets you pick between simplicity and efficiency. So next time you just have queues, you will know how to use them for a stack!

59 views

Please Login to create a Question