Consider a stack implemented using a linked list. The following operations are performed in order:
- push(10)
- push(20)
- pop()
- push(30)
- pop()
- push(40)
What is the printed state of the stack from top to bottom?
class Node: def __init__(self, data): self.data = data self.next = None class Stack: def __init__(self): self.top = None def push(self, data): new_node = Node(data) new_node.next = self.top self.top = new_node def pop(self): if self.top is None: return None popped = self.top.data self.top = self.top.next return popped def print_stack(self): current = self.top result = [] while current: result.append(str(current.data)) current = current.next print(" -> ".join(result) + " -> null") stack = Stack() stack.push(10) stack.push(20) stack.pop() stack.push(30) stack.pop() stack.push(40) stack.print_stack()
Remember that push adds to the top and pop removes from the top.
After the operations, the stack top is 40, then 10 below it, then null.
Given the stack implementation below, what happens if we call pop() on an empty stack?
class Node: def __init__(self, data): self.data = data self.next = None class Stack: def __init__(self): self.top = None def pop(self): if self.top is None: return None popped = self.top.data self.top = self.top.next return popped stack = Stack() print(stack.pop())
Check the condition when the stack is empty before popping.
The pop method returns None if the stack is empty, so no error occurs.
Look at the push method below. What is the bug that will cause incorrect stack behavior?
def push(self, data): new_node = Node(data) if self.top is None: self.top = new_node else: self.top.next = new_node self.top = new_node
Remember the linked list stack adds new nodes at the front.
The new node's next pointer must point to the current top node before updating top.
Starting with an empty stack, perform these operations:
- push(5)
- push(15)
- pop()
- push(25)
- push(35)
- pop()
- pop()
How many elements remain in the stack?
class Node: def __init__(self, data): self.data = data self.next = None class Stack: def __init__(self): self.top = None def push(self, data): new_node = Node(data) new_node.next = self.top self.top = new_node def pop(self): if self.top is None: return None popped = self.top.data self.top = self.top.next return popped def size(self): count = 0 current = self.top while current: count += 1 current = current.next return count stack = Stack() stack.push(5) stack.push(15) stack.pop() stack.push(25) stack.push(35) stack.pop() stack.pop() print(stack.size())
Count pushes and pops carefully.
After all operations, only one element remains in the stack.
Which reason best explains why a linked list implementation of a stack might be preferred over an array implementation?
Think about how arrays handle size changes.
Linked lists grow dynamically without needing to resize, unlike arrays which may need costly resizing.