Step 4 of 5
80% CompletePeek 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.
class Stack {constructor() {this.items = [];}// Push and pop methods...// Peek: Return the top element without removing itpeek() {// Check if the stack is emptyif (this.isEmpty()) {return null; // Or throw an error}// Return the last element without removing itreturn this.items[this.items.length - 1];}isEmpty() {return this.items.length === 0;}// Other methods...}
Peek Operation Visualization
The stack is empty
How Peek Works
Let's break down the peek operation step by step:
- Check if the stack is empty - Before attempting to access an element, we check if the stack is empty to avoid errors.
- 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.
- 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:
// Create a new stack and push some elementsconst stack = new Stack();stack.push(10).push(20).push(30);// Stack contains [10, 20, 30] with 30 at the top// Peek at the top elementconst 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 stackconsole.log(stack.peek()); // Output: 30console.log(stack.peek()); // Output: 30// Check if stack is empty before peekingif (!stack.isEmpty()) {const topItem = stack.peek();console.log(topItem); // Output: 30}// Pop an element and peek againstack.pop(); // Removes 30console.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
const stack = new Stack();stack.push(10).push(20).push(30);// Using peekconsole.log(stack.peek()); // Output: 30console.log(stack.peek()); // Output: 30 (same result)// Stack still contains [10, 20, 30]// Using popconsole.log(stack.pop()); // Output: 30console.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 matchesif (stack.isEmpty() || !isMatchingPair(stack.peek(), char)) {return false;}// If it matches, then popstack.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.