Learn how to implement a stack using a single queue in javascript.
Implementation
- We will be using a single queue for creating the stack.
- So every time we will add a new data to the queue, we will move the existing data to the back of the new data.
- This way we will be able to mimic the stack implementation using the queue operations.
Implementing stack using a single queue
function Stack(){ let queue = new Queue(); //Other methods go here }
Pushing data in the stack
We will enqueue the data in the queue and move the existing data to the back of the new data.
//Push this.push = function(elm){ let size = queue.size(); queue.enqueue(elm); //Move old data after the new data for(let i = 0; i < size; i++){ let x = queue.dequeue(); queue.enqueue(x); } }
Pop the data from the stack
//Pop this.pop = function(){ if(queue.isEmpty()){ return null; } return queue.dequeue(); }
Peek the data in the stack
//Peek this.peek = function(){ if(queue.isEmpty()){ return null; } return queue.front(); }
Size of the stack
//Size this.size = function(){ return queue.size(); }
Check if stack is empty
//IsEmpty this.isEmpty = function(){ return queue.isEmpty(); }
Clear the stack
//Clear this.clear = function(){ queue.clear(); return true; }
Convert the stack to an array
//ToArray this.toArray = function(){ return queue.toArray(); }
Complete Code
function Stack() { let queue = new Queue(); //Push this.push = function(elm){ let size = queue.size(); queue.enqueue(elm); //Move old data after the new data for(let i = 0; i < size; i++){ let x = queue.dequeue(); queue.enqueue(x); } } //Pop this.pop = function(){ if(queue.isEmpty()){ return null; } return queue.dequeue(); } //Peek this.peek = function(){ if(queue.isEmpty()){ return null; } return queue.front(); } //Size this.size = function(){ return queue.size(); } //IsEmpty this.isEmpty = function(){ return queue.isEmpty(); } //Clear this.clear = function(){ queue.clear(); return true; } //ToArray this.toArray = function(){ return queue.toArray(); } }
Input: let stack = new Stack(); //creating new instance of Stack stack.push(1); stack.push(2); stack.push(3); console.log(stack.peek()); console.log(stack.isEmpty()); console.log(stack.size()); console.log(stack.pop()); console.log(stack.toArray()); console.log(stack.size()); stack.clear(); //clear the stack console.log(stack.isEmpty()); Output: 3 false 3 3 [2, 1] 2 true
We can wrap this inside a closure and IIFE (Immediately Invoked Function Expression) to make all the properties and methods private.
let Stack = (function(){ return function Stack() { let queue = new Queue(); //Push this.push = function(elm){ let size = queue.size(); queue.enqueue(elm); //Move old data after the new data for(let i = 0; i < size; i++){ let x = queue.dequeue(); queue.enqueue(x); } } //Pop this.pop = function(){ if(queue.isEmpty()){ return null; } return queue.dequeue(); } //Peek this.peek = function(){ if(queue.isEmpty()){ return null; } return queue.front(); } //Size this.size = function(){ return queue.size(); } //IsEmpty this.isEmpty = function(){ return queue.isEmpty(); } //Clear this.clear = function(){ queue.clear(); return true; } //ToArray this.toArray = function(){ return queue.toArray(); } } }());
Time Complexity
# | Access | Search | Insert | Delete |
---|---|---|---|---|
Average | Θ(N) | Θ(N) | Θ(N) | Θ(1) |
Worst | O(N) | O(N) | O(N) | O(1) |
Because we are copying the data at the end of the queue after adding a new data, the insert operation changes to O(N).
Space Complexity
# | space |
---|---|
Worst | O(N) |