0% found this document useful (0 votes)
3 views

Lecture 3 Stack

This document provides a comprehensive overview of stacks, a linear data structure that follows the Last-In-First-Out (LIFO) principle, detailing its fundamental operations such as push, pop, and peek. It also covers the conversion between infix, prefix, and postfix notations, emphasizing the use of stacks in expression evaluation and practical applications like undo/redo functionality. Additionally, the document includes a Python implementation of a stack class, demonstrating how to create and manipulate stack elements.

Uploaded by

AIKO.J Breezy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Lecture 3 Stack

This document provides a comprehensive overview of stacks, a linear data structure that follows the Last-In-First-Out (LIFO) principle, detailing its fundamental operations such as push, pop, and peek. It also covers the conversion between infix, prefix, and postfix notations, emphasizing the use of stacks in expression evaluation and practical applications like undo/redo functionality. Additionally, the document includes a Python implementation of a stack class, demonstrating how to create and manipulate stack elements.

Uploaded by

AIKO.J Breezy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

stack

University Of Management and Technology

Data Structures and Algorithms


Lecture 3: Stacks and Queues
Prepared By Alpha Omar Leigh (BSc, MSc)

What You Will Learn


After this Lecture, you will have learned the following:
1. Understanding Stacks:
The fundamental concepts of a stack data structure, including the Last-In-First-Out (LIFO )
principle.
The basic operations of a stack: push, pop, and peek.
2. Infix, Prefix, and Postfix Notations:
Definitions and examples of infix, prefix, and postfix notations.
The importance of operator precedence (PEDMAS) and how it affects expression evaluation.
Step-by-step conversion of infix expressions to postfix notation using a stack.
3. Implementing a Stack in Python:
How to create a Stack class in Python using arrays.
Methods for pushing, popping, and peeking elements in the stack.
Practical examples of using the stack class to reverse a string.
Page 1 of 12
stack
4. Undo and Redo Functionality:
Implementing undo and redo operations using two stacks.
Practical application of the stack data structure to manage actions and reverse them as needed.

Understanding Stacks: A Simple Guide


What is a Stack?
A stack is a linear data structure that follows the Last-In, First-Out (LIFO) principle. This means
that the last element added to the stack is the first one to be removed. It's often compared to a
pile of plates, where the top plate is the first one you can access.

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.

Visualizing the Stack


Let's say you added the following books in this order:
1. "Things Fall Apart" by Chinua Achebe
2. "So Long a Letter" by Mariama Bâ
3. "The Palm-Wine Drinkard" by Amos Tutuola
The stack would look like this:

Top of the Stack


----------------
| The Palm-Wine Drinkard |
| So Long a Letter |
| Things Fall Apart |
----------------
Bottom 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:

Top of the Stack


----------------
| So Long a Letter |
| Things Fall Apart |
----------------
Bottom of the Stack

3. Why is Understanding Stacks Crucial?


Stacks are fundamental in computer science and have numerous applications:
Memory Management: Used in managing function calls and recursion.
Back-Button Functionality: In web browsers, the back button uses a stack to keep track of the pages
visited.
Expression Evaluation: Used in evaluating expressions like Reverse Polish Notation.

4. Fundamental Concepts of a Stack


The LIFO Principle

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.

Algorithnm and Pseudocode: Push(item)


1. Check if the stack is full: If the stack is full, return an error or handle overflow appropriately.
2. Increment the top index: Increase the top index to point to the next available position.
3. Insert the item: Place the item at the current top index position.

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

Algorithnm and Pseudocode: Pop()


1. Check if the stack is empty: If the stack is empty, return an error or handle underflow appropriately.
2. Retrieve the top item: Get the item at the current top index position.
3. Decrement the top index: Decrease the top index to point to the previous element.
4. Return the retrieved item.

if stack is empty
return "Stack Underflow"
item = stack[top]
decrement top index
return item

Peek (or Top) Operation:

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.

Stack Application : Conversion Between Infix, Prefix, and Postfix


Expressions
1. Definitions
Infix Notation
Definition: In infix notation, operators are placed between operands. This is the most common notation
used by humans.
Example: A + B
Explanation: The operator + is between the operands A and B .

Prefix Notation (Polish Notation)


Definition: In prefix notation, operators are placed before their operands.
Example: + A B
Explanation: The operator + comes before the operands A and B .

Postfix Notation (Reverse Polish Notation)


Definition: In postfix notation, operators are placed after their operands. This is the notation that
computers often use because it is easier to parse.
Example: A B +
Explanation: The operator + comes after the operands A and B .

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.

Infix to Postfix Conversion


Introduction
Infix notation is the most common way humans write mathematical expressions, with operators placed between
operands (e.g., A + B ). However, computers find it easier to process postfix notation, where operators come
after their operands (e.g., A B + ). This is because postfix notation eliminates the need for parentheses to define
the order of operations, making it simpler to evaluate expressions using a stack.

Operator Precedence: PEDMAS


Computers use the PEDMAS rule (Parentheses, Exponents, Division and Multiplication, Addition and
Subtraction) to determine the order of operations. This is similar to the BODMAS rule but emphasizes the use
of parentheses and exponents.

Operator Description Precedence


() Parentheses Highest
^ Exponents High
* Multiplication Medium
/ Division Medium
+ Addition Low
- Subtraction Low

Algorithm for Infix to Postfix Conversion


1. Initialize an empty stack for operators and an empty list for the output (postfix expression).
2. Scan the infix expression from left to right.
Page 7 of 12
stack
3. For each character in the infix expression:
If the character is an operand, add it to the output list.
If the character is an operator:
While the stack is not empty and the precedence of the operator at the top of the stack
is greater than or equal to the precedence of the current operator, pop operators from
the stack to the output list.
Push the current operator onto the stack.
If the character is a left parenthesis ( , push it onto the stack.
If the character is a right parenthesis ) :
Pop operators from the stack to the output list until a left parenthesis ( is encountered.
Discard the pair of parentheses.
4. Pop all remaining operators from the stack to the output list.

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*/

Example 1: Converting A + B * C / D to Postfix


1. Infix Expression: A + B * C / D
2. Conversion Steps:
A (operand) → Add to output: A
+ (operator) → Push onto stack: Stack: [+]
B (operand) → Add to output: A B
* (operator) → Push onto stack: Stack: [+, *]
C (operand) → Add to output: A B C
/ (operator) → Pop * from stack to output, then push / onto stack: A B C * , Stack: [+/]
D (operand) → Add to output: A B C * D
Pop remaining operators from stack to output: A B C * D / +
Postfix Expression: A B C * D / +

Examples
Example 2: 3 + (9 - 5) * 2

Token Stack Output


3 empty 3
+ + 3
( +( 3
9 +( 39
- +-( 39
5 +-( 395
) + 395-
* +* 395-
2 +* 395-2
(end of expression) + 395-2*
(pop remaining operator) 395-2*+

Evaluating 3 + (9 - 5) * 2 in Postfix Notation


Page 9 of 12
stack
Token Stack Output
3 3
9 39
5 395
- 34
2 342
* 38
+ 11

Final result: 11

Solve in Class
A + B * (C ^ D - E) ^ (F + G * H) - I

Stack Implementation Using Python


1. Class Definition and Attributes:

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:

def push(self, item):


if self.top == self.size - 1:
raise Exception("Stack Overflow")
self.top += 1
self.stack[self.top] = item

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

created with the evaluation version of Markdown Monster


Page 11 of 12
stack

Page 12 of 12

You might also like