Lecture 3 Stack
Lecture 3 Stack
1. Key characteristics:
Linear: Elements are arranged in a linear sequence.
LIFO: The last element added is the first one to be removed.
Bounded or unbounded: Stacks can be bounded (fixed size) or unbounded (dynamically resizing).
Think of it as a stack of plates in a cafeteria:
You can only take the plate that's on top.
Page 2 of 12
stack
When placing a new plate, it goes to the top of the stack.
If you need to remove a book, you start with "The Palm-Wine Drinkard" because it is on the top. After removing
it, the stack looks like this:
LIFO stands for Last In, First Out. This principle means that the last item added to the stack is
the first one to be removed.
Example: Imagine people getting in and out of an elevator. The last person who enters is the first to get out.
Basic Operations
Every data structure is defined by the operations it supports. For stacks, these operations are straightforward but
Page 3 of 12
stack
vital:
Push Operation
Adds an element to the top of the stack. If the stack is full, this operation might result in a stack
overflow.
if stack is full
return "Stack Overflow"
increment top index
stack[top] = item
Pop Operation
Removes and returns the topmost element of the stack.If the stack is empty, attempting a pop
can cause a stack underflow.
Page 4 of 12
stack
if stack is empty
return "Stack Underflow"
item = stack[top]
decrement top index
return item
Observes the topmost element without removing it. Useful when you want to inspect the current
top element without altering the stack's state.
Peek()
1. Check if the stack is empty: If the stack is empty, return an error or handle underflow appropriately.
2. Return the top item: Retrieve the item at the current top index position without modifying the stack.
if stack is empty
return "Stack Underflow"
return stack[top]
isEmpty Operation
Page 5 of 12
stack
isEmpty()
Check the top index: If the top index is equal to -1 (or any other appropriate value indicating an
empty stack), return true. Otherwise, return false.
if top index is -1
return true
else
return false
NOTE
Stack Overflow occurs when you attempt to push an element onto a stack that is already full. This can
happen if the stack has a fixed size and you exceed that capacity. Stack Underflow occurs when you
attempt to pop an element from an empty stack. This can happen if you try to access an element that
doesn't exist.
Examples
Page 6 of 12
stack
Infix Prefix Postfix
a+b*c + a (* b c) abc*+
(a + b) * c * (+ a b) c ab+c*
Understanding Conversion
Humans typically understand infix notation because it’s the most common way we write
mathematical expressions, with operators placed between operands (e.g., A + B) . However,
computers often find it easier to process prefix (operators before operands, e.g., + A B ) or
postfix notation (operators after operands, e.g., A B +) . Computers can evaluate prefix and
postfix expressions directly using a stack, which simplifies the process by eliminating the need for
parentheses to define the order of operations. This makes postfix notation particularly efficient
for computers to handle.
Pseudocode
function infixToPostfix(expression):
stack = empty stack
output = empty list
for each character in expression:
if character is operand:
add character to output
else if character is '(':
push character onto stack
else if character is ')':
while stack is not empty and stack.top() != '(':
add stack.pop() to output
pop '(' from stack
else if character is operator:
while stack is not empty and precedence(stack.top()) >= precedence(character):
add stack.pop() to output
push character onto stack
while stack is not empty:
add stack.pop() to output
return output
Example 1: A + B * C / D
Token Stack Output
A empty A
+ + A
B + AB
* +* AB
C +* ABC
/ +*/ ABC
Page 8 of 12
stack
Token Stack Output
D +*/ ABCD
(end of expression) + ABCD*
(pop remaining operator) ABCD*/
Examples
Example 2: 3 + (9 - 5) * 2
Final result: 11
Solve in Class
A + B * (C ^ D - E) ^ (F + G * H) - I
class Stack:
def __init__(self, size):
self.size = size
self.stack = [None] * size
self.top = -1
Here, we define a Stack class with a constructor ( __init__ ) that takes a single argument, size . This represents
the maximum size the stack can hold.
self.size : Stores the maximum size of the stack.
self.stack : Creates an array of size size to hold the stack elements. It's initialized with None values to
indicate empty slots.
self.top : Keeps track of the index of the top element in the stack. Initially, it's set to -1 since the stack is
empty.
2. push(item) Method:
The push(item) method adds a new element ( item ) to the top of the stack.
Page 10 of 12
stack
It first checks if the stack is full ( self.top == self.size - 1 ). If it is, it raises a Stack Overflow exception.
If the stack has space, it increments the top index to point to the next available position in the array.
Finally, it assigns the item to the self.stack[self.top] position, effectively placing it on top of the stack.
3. pop() Method:
def pop(self):
if self.top == -1:
raise Exception("Stack Underflow")
item = self.stack[self.top]
self.top -= 1
return item
The pop() method removes and returns the top element from the stack.
It first checks if the stack is empty ( self.top == -1 ). If it is, it raises a Stack Underflow exception.
If the stack has elements, it retrieves the element at the self.top index ( item ).
Then, it decrements the top index to point to the new top element.
Finally, it returns the removed element ( item ).
4. peek() Method:
def peek(self):
if self.top == -1:
raise Exception("Stack is empty")
return self.stack[self.top]
The peek() method returns the value of the top element in the stack without removing it.
Similar to pop() , it checks for an empty stack ( self.top == -1 ) and raises an exception if so.
If the stack is not empty, it returns the element at the self.top index without modifying the top or
removing the element.
Classwork
Page 12 of 12