Step 4 of 5

80% Complete

Peek Operation

Learn how to view the top element without removing it

The Peek Operation

The peek operation (sometimes called "top") allows you to view the top element of the stack without removing it. This is useful when you need to check what's next in the stack without altering its structure.

Think of it like looking at the top plate in a stack of plates without actually taking it off the stack.

Implementing Peek

In our array-based implementation, the peek operation simply returns the last element of the array (which represents the top of our stack) without removing it.

Peek Implementation
class Stack {
constructor() {
this.items = [];
}
// Push and pop methods...
// Peek: Return the top element without removing it
peek() {
// Check if the stack is empty
if (this.isEmpty()) {
return null; // Or throw an error
}
// Return the last element without removing it
return this.items[this.items.length - 1];
}
isEmpty() {
return this.items.length === 0;
}
// Other methods...
}

Peek Operation Visualization

The stack is empty

Stack remains unchanged: [10, 20, 30, 40], peek returns: 40

How Peek Works

Let's break down the peek operation step by step:

  1. Check if the stack is empty - Before attempting to access an element, we check if the stack is empty to avoid errors.
  2. Handle empty stack - If the stack is empty, we return null or throw an error, depending on how we want to handle this edge case.
  3. Return the top element - We access the last element of the array (which is the top of our stack) using this.items[this.items.length - 1] and return it without modifying the array.

Key Points About Peek:

  • Time Complexity: O(1) - The peek operation is constant time, meaning it takes the same amount of time regardless of how many elements are in the stack.
  • Non-destructive: Unlike pop, peek does not modify the stack. The stack remains unchanged after a peek operation.
  • Empty Stack Handling: Always check if the stack is empty before peeking to avoid errors.

Peek Operation in Action

Here's an example of using the peek operation:

Using Peek
// Create a new stack and push some elements
const stack = new Stack();
stack.push(10).push(20).push(30);
// Stack contains [10, 20, 30] with 30 at the top
// Peek at the top element
const topElement = stack.peek();
console.log(topElement); // Output: 30
// Stack still contains [10, 20, 30] with 30 at the top
// We can peek multiple times without changing the stack
console.log(stack.peek()); // Output: 30
console.log(stack.peek()); // Output: 30
// Check if stack is empty before peeking
if (!stack.isEmpty()) {
const topItem = stack.peek();
console.log(topItem); // Output: 30
}
// Pop an element and peek again
stack.pop(); // Removes 30
console.log(stack.peek()); // Output: 20

Peek vs. Pop

It's important to understand the difference between peek and pop:

Peek

  • Returns the top element
  • Does NOT remove the element
  • Stack remains unchanged
  • Can be called multiple times with the same result

Pop

  • Returns the top element
  • Removes the element from the stack
  • Stack is modified
  • Consecutive calls return different elements
Peek vs. Pop Example
const stack = new Stack();
stack.push(10).push(20).push(30);
// Using peek
console.log(stack.peek()); // Output: 30
console.log(stack.peek()); // Output: 30 (same result)
// Stack still contains [10, 20, 30]
// Using pop
console.log(stack.pop()); // Output: 30
console.log(stack.pop()); // Output: 20 (different result)
// Stack now contains only [10]

Common Use Cases for Peek

The peek operation is particularly useful in these scenarios:

  • Decision Making: When you need to make a decision based on the top element without removing it.
  • Validation: Checking if the next element to be processed meets certain criteria.
  • Expression Evaluation: In algorithms like expression evaluation, you might need to check the top operator without removing it.
  • Lookahead: When you need to "look ahead" at what's coming next in the stack.

Example: Balanced Parentheses

In a balanced parentheses algorithm, you might peek at the top of the stack to check if it matches the current closing bracket before popping.

function isBalanced(expression) {
const stack = new Stack();
for (let char of expression) {
if (char === '(' || char === '[' || char === '{') {
stack.push(char);
} else if (char === ')' || char === ']' || char === '}') {
// Peek first to check if the top matches
if (stack.isEmpty() || !isMatchingPair(stack.peek(), char)) {
return false;
}
// If it matches, then pop
stack.pop();
}
}
return stack.isEmpty();
}
function isMatchingPair(open, close) {
return (open === '(' && close === ')') ||
(open === '[' && close === ']') ||
(open === '{' && close === '}');
}

Check Your Understanding

Next Steps

Now that you understand the three core operations of a stack (push, pop, and peek), let's explore some real-world applications of stacks in the next section.