The task at hand is to implement a queue using a stack data structure, with the push
(adding an element) and pop
(removing an element) operations as the low-level data structure.
A queue is a FIFO (First In First Out), while a stack is a LIFO (Last In First Out) data structure.
A stack pushes a new element to the top of the stack and also pops the element at the top. A queue, however, dequeues (removes) an element from the top of the queue, but it enqueues (inserts) an element at the bottom.
There are two methods used to implement a queue using the stack data structure. One method uses two stacks while the other uses one.
This method ensures that the oldest inserted element is always at the top of stack1
so that the deQueue
operation just pops from stack1
. To put the element at the top of stack1
, stack2
is used.
enqueue(x)
:
While stack1
is not empty, push everything from stack1
to stack2
.
Push x
to stack1
.
Push everything back to stack1
.
dequeue(x)
:
If stack1
is empty, display an error message.
Pop an item from stack1
and return it.
The code snippet below puts the above algorithm into code:
#include <bits/stdc++.h>using namespace std;struct Queue {stack<int> stack1, stack2;void enqueue(int x){// Move all elements from s1 to s2while (!stack1.empty()) {stack2.push(stack1.top());stack1.pop();}// Push item into s1stack1.push(x);// Push everything back to s1while (!stack2.empty()) {stack1.push(stack2.top());stack2.pop();}}// Dequeue an item from the queueint dequeue(){// if first stack is emptyif (stack1.empty()) {cout << "queue is Empty";exit(0);}// Return the top of stack1int x = stack1.top();stack1.pop();return x;}};int main(){Queue q;q.enqueue(3);q.enqueue(4);q.enqueue(5);cout << q.dequeue() << endl;cout << q.dequeue() << endl;cout << q.dequeue() << endl;return 0;}
A queue can also be implemented using only one user stack; this method uses recursion.
enqueue(x)
:
x
to stack_
.dequeue(x)
:
If stack_
is empty, then display an error message.
If stack_
has only one element, then return it.
Recursively pop everything from the stack_
, store the popped item
in a variable ret
, push the ret
back to stack_
, and return ret
.
Step 3 of
dequeue()
makes sure that the last popped item is always returned. Recursion stops when there is only one item in thestack_
, so the last element ofstack_
indequeue()
is returned, while all other items are pushed back instack_
.
The code snippet below puts the above algorithm into code:
#include <bits/stdc++.h>using namespace std;struct Queue {stack<int> stack_;// Enqueue an item to the queuevoid enqueue(int x){stack_.push(x);}// Dequeue an item from the queueint dequeue(){if (stack_.empty()) {cout << "Queue is empty" << endl;;exit(0);}// pop an item from the stackint x = stack_.top();stack_.pop();// if stack becomes empty, return// the popped itemif (stack_.empty())return x;// recursive callint ret = dequeue();// push popped item back to the stackstack_.push(x);// return the result of deQueue() callreturn ret;}};int main(){Queue q;q.enqueue(3);q.enqueue(4);q.enqueue(5);cout << q.dequeue() << endl;cout << q.dequeue() << endl;cout << q.dequeue() << endl;return 0;}