Implementation of Stack using Queue
A stack is a linear data structure that follows the LIFO principle, which means that the element inserted first will be removed last. On the other hand, Queue is a linear data structure that follows the FIFO principle, which means that the added element will be removed first. Now, we will discuss how we can implement the Stack using Queue.
There are two approaches to implement stack using Queue:
- First, we can make the push operation costly.
- Second, we can make the pop operation costly.
First approach: Making a push operation costly
Let’s understand through an example.
Suppose we have a list given below:
1, 5, 3, P, 2, P
In the above list, ‘P’ means that we have to implement the pop operation whereas, the integers 1, 5, 3, and 2 are to be inserted in the stack. We will implement through a Queue. Or we can say that we will implement the push and pop operations through Queue.
First, we create two empty Queues as shown below:
In the above, we have created two Queues, i.e., Queue1 and Queue2. First, we push element 1 into the Queue1, so front and rear point to element 1 as shown below:
After inserting element 1, we have to insert element 5 into Queue1. First, we pop the element 1 from the Queue1 and push it into the Queue2, and then we push the element 5 into the Queue1 as shown below:
As we can observe in the above figure, the front and rear in Queue1 point to element 5, whereas the front and rear in Queue2 point to element 1. Once the insertion of element 5 is completed, element 1 from Queue2 moves back to Queue2. In Queue1, the front will point to element 5, and rear will point to element 1, as shown below:
Now the next element is 3 which we have to insert in Queue1. In order to achieve this, all the elements, i.e., 5 and 1 from the Queue1, will be popped out and added into the Queue2.
Once the elements are popped out from the Queue1, the element 3 will be pushed into the Queue1, and front will point to element 3 as shown below:
After pushing element 3 in Queue1, we will pop all the elements from Queue2 and push them back to Queue1. The front will point to element 3 and the rear will point to element 1, as shown below:
The next operation is a pop operation. Till now, we have observed that the push operation is costly, but the pop operation takes O(1) time. So, we will pop element 3 from Queue1 and update the front pointer. The popped element will be printed in the output. Now front will point to element 5 as shown below:
The next element to be inserted is 2. First, we will pop all the elements from the Queue1 and add into the Queue2 as shown below:
Once all the elements are popped out from the Queue1, element 2 would be pushed into the Queue1. The front and rear of Queue1 will point to element 2 as shown below:
After inserting the element into Queue1, we will pop all the elements from Queue2 and move them back to Queue1 as shown below:
As we can observe in the above figure, the front points to the element 2 while the rear points to element 1.
The next operation is the pop operation. In the pop operation, element 2 would be popped out from the Queue1 and gets printed in the output. The front pointer gets updated and points to element 5 as shown below:
The output is 3, 2.
If we want to verify whether the output is correct or not, then we can use stack. First, we push element 1 into the stack as shown below:
The next element 5 is pushed into the stack as shown below:
The next element is 3 will be pushed into the stack as shown below:
Now pop operation will be called, and element 3 will be popped out from the stack. The element 3 gets printed in the output as shown below:
The next element is 2 to be pushed into the stack:
After inserting 2, the pop operation will be called, and element 2 will be popped out from the stack. The element 2 gets printed in the output.
The output is 3, 2, which is same as the output generated through the implementation of the Queue.
Time Complexity
If we implement the stack through Queue, then push operation will take O(n) time as all the elements need to be popped out from the Queue1 and push them back to Queue1.
The pop operation will take O(1) time because we need to remove front element from the Queue.
Algorithm (when the push operation is costly)
Push Algorithm
The following are the steps to perform the push operation:
Step 1: Consider two queues, i.e., Q1 and Q2, and the element to be inserted in the queue is x.
Step 2: if Q1.isEmpty() then
       Q1.enqueue(x);
       else
       size:= Q1.size();
       for i=0…size do
       Q2.enqueue(Q1.dequeue());
       end
       Q1.enqueue(x);
       for j=0….size do
       Q1.enqueue(Q2.dequeue());
       end
Pop Algorithm
The following are the steps to perform the pop operation:
Step 1: Consider two queues, i.e., Q1 and Q2, and we want to remove the element from the front of the queue.
Step 2: item:= Q1.dequeue();
Step 3: return item;
Second approach: Making pop operation costly
Suppose we have a list given below:
1, 5, 3, P, 2, P
We will consider two Queues, i.e., Queue1 and Queue2 as we have done in the previous approach. First, we will push element 1 into the Queue1 as shown below:
The next element is 5 which will be pushed into the Queue1 as shown below:
The next element is 3 which will also be pushed into the Queue1 as shown below:
Now we have to implement the pop operation on the Queue1. In this case, we will first pop all the elements except the last pointed by rear and add them into the Queue2. The last element will be removed from the Queue1 and gets printed in the output as shown below:
Now we will move the elements of Queue2 back to Queue1.
The next element is 2 which will be inserted into the Queue1 as shown below:
The next operation is the pop operation. In this operation, first, we need to pop all the elements from Queue1 except the last element pointed by rear and add it into the Queue2. The last element, i.e., 2 will be removed from the Queue1 and gets printed in the output as shown below:
The elements added in the Queue2 will be moved back to Queue1 as shown below:
As we can observe in the above figure that the output generated as 3, 2 and elements remaining in the Queue are 1, 5.
Time Complexity
In the above case, the push operation takes O(1) time because on each push operation the new element is added at the end of the Queue. On the other hand, pop operation takes O(n) because on each pop operation, all the elements are popped out from the Queue1 except the last element and pushed it into the Queue2. The last element from the Queue1 will be deleted and then all the elements from Queue2 are moved back to the Queue1.
Algorithm (when the pop operation is costly)
Push Algorithm
The following are the steps to perform the push operation:
Step 1: Consider two queues, i.e., Q1 and Q2, and the element to be inserted in the queue is x.
Step 2: element= Q1.enqueue(x);
Step 3: return element;
Pop Algorithm
The following are the steps to delete an element from the queue:
Step 1: Consider two queues, i.e., Q1 and Q2, and we want to remove an element from the queue.
Step 2: if !Q1.isEmpty() then
       size:= Q1.size();
       for i=0…size-1 do
       Q2.enqueue(Q1.dequeue());
       end
       int item = Q1.dequeue();
       for j=0…size-1 do
       Q1.enqueue(Q2.dequeue());
       end