Skip to main content

Implementing Stacks

1. Creating Stack Class

Method Description Parameters Return Value
constructor() Initializes an empty stack None Stack instance
push(element) Adds an element to the top of the stack element: any type undefined
pop() Removes and returns the top element from the stack None Top element or undefined if stack is empty
peek() Returns the top element without removing it None Top element or undefined if stack is empty
isEmpty() Checks if the stack is empty None Boolean: true if empty, false otherwise
size() Returns the number of elements in the stack None Number: current size of the stack

Example: Basic Stack Usage

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  pop() {
    return this.items.pop();
  }

  peek() {
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }

  size() {
    return this.items.length;
  }
}

const stack = new Stack();
stack.push(1);
stack.push(2);
console.log(stack.peek()); // 2
console.log(stack.pop());  // 2
console.log(stack.size()); // 1

2. Creating Stack

Operation Description Time Complexity Space Complexity
push(element) Adds an element to the top of the stack O(1) O(1)
pop() Removes and returns the top element from the stack O(1) O(1)
peek()/top() Returns the top element without removing it O(1) O(1)
isEmpty() Checks if the stack is empty O(1) O(1)
size() Returns the number of elements in the stack O(1) O(1)

Example: Implementing a Stack in JavaScript

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  pop() {
    if (this.isEmpty()) {
      return "Underflow";
    }
    return this.items.pop();
  }

  peek() {
    if (this.isEmpty()) {
      return "No elements in Stack";
    }
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }

  size() {
    return this.items.length;
  }
}

// Example usage
const stack = new Stack();
stack.push(10);
stack.push(20);
console.log(stack.peek()); // 20
console.log(stack.pop());  // 20
console.log(stack.size()); // 1

3. Pushing Elements

Pushing an element onto a stack adds it to the top of the stack, following LIFO (Last In, First Out) order.

Operation Time Complexity Description
push(element) O(1) Adds an element to the top of the stack

Example: Pushing Elements to a Stack

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }
}

const stack = new Stack();
stack.push(10);
stack.push(20);
console.log(stack.items); // [10, 20]

4. Popping Elements

Method Description Time Complexity Space Complexity
pop() Removes and returns the top element from the stack O(1) O(1)

Example: Popping Elements from a Stack

const stack = [10, 20, 30];
const poppedElement = stack.pop();
console.log(poppedElement); // Output: 30
console.log(stack);         // Output: [10, 20]
Note: Popping from an empty stack typically results in undefined or throws an error depending on the implementation.

5. Peeking Top Element

Peeking at the top element of a stack is a common operation that allows you to inspect the most recently added item without removing it from the stack.

Operation Description Time Complexity Space Complexity
peek() Returns the top element of the stack without removing it O(1) O(1)

Example: Peeking at the top element in a stack

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  peek() {
    if (this.isEmpty()) {
      return null;
    }
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

const stack = new Stack();
stack.push(10);
stack.push(20);
stack.push(30);

console.log(stack.peek()); // Output: 30

6. Checking if Empty

Method Description Time Complexity Space Complexity
isEmpty() Returns true if the stack is empty, otherwise false O(1) O(1)

Example: Checking if Stack is Empty

class Stack {
  constructor() {
    this.items = [];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

const stack = new Stack();
console.log(stack.isEmpty()); // true

stack.push(10);
console.log(stack.isEmpty()); // false

7. Getting Stack Size

Method Description Time Complexity Space Complexity
size() Returns the number of elements in the stack O(1) O(1)

Example: Getting Stack Size

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  size() {
    return this.items.length;
  }
}

const stack = new Stack();
stack.push(10);
stack.push(20);
console.log(stack.size()); // Output: 2

8. Clearing Stack

Clearing a stack involves removing all elements from the stack, leaving it empty. The method used to clear a stack depends on the implementation (array-based or linked list-based).

Operation Description Time Complexity Space Complexity
clear() Removes all elements from the stack, making it empty. O(n) O(1)

Example: Clearing a Stack (Array-based)

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  clear() {
    this.items = [];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

const stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);

console.log(stack.isEmpty()); // false
stack.clear();
console.log(stack.isEmpty()); // true

Example: Clearing a Stack (Linked List-based)

class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class Stack {
  constructor() {
    this.top = null;
  }

  push(data) {
    const newNode = new Node(data);
    newNode.next = this.top;
    this.top = newNode;
  }

  clear() {
    this.top = null;
  }

  isEmpty() {
    return this.top === null;
  }
}

const stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);

console.log(stack.isEmpty()); // false
stack.clear();
console.log(stack.isEmpty()); // true

9. Implementing with Two Queues

Stacks can be implemented using two queues to simulate LIFO (Last In, First Out) behavior. This approach uses one queue for pushing elements and another to assist in reversing the order during pop operations.

Operation Description Time Complexity Space Complexity
push(element) Enqueues the element to the first queue. O(1) O(n)
pop() Transfers all but the last element from queue1 to queue2, then removes and returns the last element. Swaps queues afterward. O(n) O(n)
top() Similar to pop but returns the top element without removing it. O(n) O(n)
isEmpty() Checks if both queues are empty. O(1) O(1)

Example: Stack Implementation Using Two Queues

class StackWithQueues {
  constructor() {
    this.queue1 = [];
    this.queue2 = [];
  }

  push(element) {
    this.queue1.push(element);
  }

  pop() {
    if (this.queue1.length === 0) return null;

    while (this.queue1.length > 1) {
      this.queue2.push(this.queue1.shift());
    }

    const popped = this.queue1.shift();
    [this.queue1, this.queue2] = [this.queue2, this.queue1];
    return popped;
  }

  top() {
    if (this.queue1.length === 0) return null;

    const temp = [];
    while (this.queue1.length > 1) {
      temp.push(this.queue1.shift());
    }

    const topElement = this.queue1[0];
    temp.push(topElement);
    [this.queue1, this.queue2] = [temp, []];
    return topElement;
  }

  isEmpty() {
    return this.queue1.length === 0 && this.queue2.length === 0;
  }
}

// Example usage:
const stack = new StackWithQueues();
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.pop()); // 3
console.log(stack.top()); // 2

Was this article helpful?