You are on page 1of 64

Data Structure and

Algorithm: Stacks

By
Dr. Richa Sharma
Assistant Professor
ITS Engineering College
Greater noida

1
Applications of Stacks
Reversing a string
Factorial Calculation
Parenthesis Checker
Stacks can be used to check the validity of parentheses in any algebraic
expression.

For example, an algebraic expression is valid if for every open bracket


there is a corresponding closing bracket.

For example, the expression (A+B} is invalid but an expression {A + (B –


C)} is valid.
Algebraic
Expression
• An algebraic expression is a legal combination of operands
and the operators.
• Operand is the quantity (unit of data) on which a
mathematical operation is performed.
• Operand may be a variable like x, y, z or a constant like 5,
4,0,9,1 etc.
• Operator is a symbol which signifies a mathematical or logical
operation between the operands. Example of familiar
operators include +,-,*, /, ^
• Considering these definitions of operands and operators now
we can write an example of expression as x+y*z.
Infix, Prefix and Postfix expression

Infix, Postfix and Prefix notations are the ways of writing


and evaluating Arithmetic & Algebraic expressions.

(a) Infix notation: A + B


When we write any arithmetic expression in infix
notation, operators are written in-between their
operands.
For example
(A+B) or A * ( B + C ) / D is in infix notation.
(b) Postfix notation (“Reverse Polish notation”): A B +
When we write any arithmetic expression in Postfix notation, operators
are written after their operands.
For example
A B C + * D / is in postfix notation

(c) Prefix notation (“Polish notation”): + A B


When we write any arithmetic expression in Prefix notation, operators
are written before their operands.
For example
/ * A + B C D is in Prefix notation
Infix, Postfix and Prefix
Expressions
• INFIX: From our schools times we have been familiar with the
expressions in which operands surround the operator, e.g. x+y, 6*3 etc
this way of writing the Expressions is called infix notation.

• POSTFIX: Postfix notation are also Known as Reverse Polish Notation


(RPN). They are different from the infix and prefix notations in the
sense that in the postfix notation, operator comes after the operands,
e.g. xy+, xyz+* etc.

• PREFIX: Prefix notation also Known as Polish notation.In the prefix


notation, as the name only suggests, operator comes before the
operands, e.g. +xy, *+xyz etc.
Examples of infix to prefix and
post fix
Infix PostFix Prefix

A+B AB+ +AB

(A+B) * (C + D) AB+CD+* *+AB+CD

A-B/(C*D^E) ABCDE^*/- -A/B*C^DE


Point to be consider while Parsing Expression

Operator precedence and

Associativity 

Precedence and associativity determines the order of


evaluation of an expression.
What is Precedence?

To describe precedence we can say it as priority of operator


mean which operator will compute operand first. Suppose we
have two different operators which is in between of operands.
Now which operator will take the operand first to perform
evaluation, is decided by the precedence of an operator over
others.
For example −
a*b+c
Multiplication operator has higher precedence than the
addition operator. So a * b will be evaluated first and then
(result of a*b) + c will be evaluated.
Associativity

When in an expression there are two operators with the


same precedence then we will see the Associativity of
operators. Associativity is of two types left Associativity
and right Associativity.
For example, in expression a – b + c, both – and +
have the same precedence, then which part of the
expression will be evaluated first, is determined by the
associativity of those operators. Here, both – and + are
left-associative, so the expression will be evaluated as (a
– b) + c.
Operator Priorities
• How do you figure out the operands of an
operator?
–a+b*c
–a*b+c/d
• This is done by assigning operator priorities.
– priority(*) = priority(/) > priority(+) = priority(-)
• When an operand lies between two operators, the
operand associates with the operator that has
higher priority.
Suppose that we would like to
rewrite A+B*C in
postfix
• Applying the rules of precedence,we obtained

A+B*C
A+(B*C) Parentheses for emphasis

A+ Convert the multiplication,Let D=BC*

(BC*) Convert the addition

A+D
A(D)+ Postfix Form
ABC*+
Postfix
Examples
Infix Postfix Evaluation

2-3*4+5 234*-5+ -5

(2 - 3) * (4 + 5) 23-45+* -9

2- (3 * 4 +5) 234*5+- -15


Exampl
e
• ( 5 + 6) * 9 +10
will be
• 5 6 + 9 * 10 +
When do we need to do
conversion
So, what is actually done is expression is scanned from
user in infix form; it is converted into prefix or postfix
form and then evaluated without considering the
parenthesis and priority of the operators.
Infix to prefix and postfix
1. A+B–C
2. A+B*C
3. (A + B) / (C – D)
4. ( ( A + B ) * ( C – D ) + E ) / (F + G)
5. A+B*C/D–E
6. (A+B*(C-D))/E
7. A * B + C / D
8. (A - B/C) * (A/K-L)
Infix to prefix conversion

Input : A * B + C / D
Output : + * A B/ C D

Input : (A - B/C) * (A/K-L)

Output : *-A/BC-/AKL
Algorithm to convert Infix to postfix
expression
Suppose we want to convert 2*3/(2-1)+5*3 into Postfix form,

Postfix Expression is 23*21-/53*+


Suppose we want to convert 2*3/(2-1)+5*3 into Postfix form,

Expression Stack Output


2 Empty 2
* * 2
3 * 23
/ / 23*
( /( 23*
2 /( 23*2
- /(- 23*2
1 /(- 23*21
) / 23*21-
+ + 23*21-/
5 + 23*21-/5
* +* 23*21-/53
3 +* 23*21-/53
Empty 23*21-/53*+
So, the Postfix Expression is 23*21-/53*+
Evaluation a postfix
expression
• Each operator in a postfix string refers to the previous two
operands in the string.
• Suppose that each time we read an operand we push it into a
stack. When we reach an operator, its operands will then be top
two elements on the stack
• We can then pop these two elements, perform the indicated
operation on them, and push the result on the stack.
• So that it will be available for use as an operand of the next
operator.
Evaluating Postfix
Notation
• Use a stack to evaluate an expression in postfix
notation.
• The postfix expression to be evaluated is scanned
from left to right.
• Variables or constants are pushed onto the stack.
• When an operator is encountered, the indicated
action is performed using the top elements of the
stack, and the result replaces the operands on the
stack.
Evaluating a postfix
expression
• Initialise an empty stack
• While token remain in the input stream
–Read next token
–If token is a number, push it into the stack
–Else, if token is an operator, pop top two tokens
off the stack,apply the operator, and push the
answer back into the stack
• Pop the answer off the stack.
Algorithm: Evaluation of Postfix
Expression
Example: postfix expressions (cont.)
Postfix expressions:
Algorithm using stacks
(cont.)
Example:
Question : Evaluate the following expression
in postfix :
623+-382/+*2^3+
Final answer is
• 49
• 51
• 52
• 7
• None of these
Evaluate- 623+-
382/+*2^3+
Symbol opnd1 opnd2 value opndstk
6 6
2 6,2
3 6,2,3
+ 2 3 5 6,5
- 6 5 1 1
3 6 5 1 1,3
Evaluate- 623+-
382/+*2^3+
Symbol opnd1 opnd2 value opndstk
8 6 5 1 1,3,8
2 6 5 1 1,3,8,2
/ 8 2 4 1,3,4
+ 3 4 7 1,7
* 1 7 7 7
2 1 7 7 7,2
^ 7 2 49 49
3 7 2 49 49,3
+ 49 3 52 52
Practice Test
Q2:
Solution
Q 3: Consider the infix expression given as 9
– ((3 * 4) + 8) / 4. Evaluate the expression.
Solution
• The infix expression 9 – ((3 * 4) + 8) / 4 can be written as 9 3 4 * 8 +
4 / – using postfix notation.
Applications of stacks
• Applications of stacks:
• 1. Stack is used by compilers to check for balancing of parentheses,
brackets and braces. 2. Stack is used to evaluate a postfix expression.
3. Stack is used to convert an infix expression into postfix/prefix form.
4. In recursion, all intermediate arguments and return values are
stored on the processor‘s stack.
5. During a function call the return address and arguments are pushed
onto a stack and on return they are popped off.
Recursion
A recursive function is defined as a function that calls itself to solve a smaller
version of its task until a final call is made which does not require a call to itself.
Since a recursive function repeatedly calls itself, it makes use of the system
stack to temporarily store the return address and local variables of the calling
function.
Every recursive solution has two major cases. They are
 Base case, in which the problem is simple enough to be solved directly
without making any further calls to the same function.
Recursive case, in which first the problem at hand is divided into simpler sub-
parts. Second the function calls itself but with sub-parts of the problem
obtained in the first step. Third, the result is obtained by combining the
solutions of simpler sub-parts.
Recursive Functions
Example
Recursion Types (Tail of Recursion)
• Any recursive function can be characterized based on:
 whether the function calls itself directly or indirectly (direct or
indirect recursion),
 whether any operation is pending at each recursive call (tailrecursive
or not), and
 the structure of the calling pattern (linear or tree-recursive).
TYPES
• Direct Recursion A function is said to be directly recursive if it explicitly calls itself. Here,
the function Func() calls itself for all positive values of n, so it is said to be a directly
recursive function.
• Indirect Recursion A function is said to be indirectly recursive if it contains a call to
another function which ultimately calls it. These two functions are indirectly recursive as
they both call each other.
• Tail Recursion A recursive function is said to be tail recursive if no operations are pending
to be performed when the recursive function returns to its caller. when the called
function returns, the returned value is immediately returned from the calling function.
Tail recursive functions are highly desirable because they are much more efficient to use as
the amount of information that has to be stored on the system stack is independent of the
number of recursive calls.
Tail of Recursion
Tower of Hanoi
The tower of Hanoi is one of the main applications of recursion. It says,
‘if you can solve n–1 cases, then you can easily solve the nth case’.
Recursion Vs Iteration
Difference
Recursion vs Iteration
i) In recursion, function call itself until the base or terminating condition is not true.
On other hand, In Iteration set of instructions repeatedly executes until the condition fails. For
example –  when you use loop (for, while etc.) in your code.
ii) Iterative approach involves four steps, Initialization , condition, execution and  updation.
In recursive function, only base condition (terminate condition) is specified.
iii) Recursion keeps your code short and simple Whereas iterative approach makes your code
longer.
iv) Recursion is slower as compared to iterative approach due to overhead of maintaining call stack.
v) Recursion takes more memory than iteration due to overhead of maintaining call stack  .
vi) If recursion is not terminated (or base condition is not specified) than it creates stack overflow
(where your system runs out of memory).
vii) Any recursive problem can be solved iteratively . But you can’t  solve all problems using recursion.
Recursion Vs Iteration
1 int calfactorial(int n) 1 int calfactorial (int n){
2 { 2  
3   /* Base condition if n equals to 1 then return 1 */ 3   int fac = 1; Java
4   if(n==1) 4  
5      return 1; 5    for (int i = 2; i <= n; i++){
6   6  
7   else 7        fac = fac * i;
8  
8      /* Recursive call */ 9    }
9      return (n * calfactorial(n-1) ); 1  
1 } 0     return fac;
0 1  
1 }
1
2
1
3
On the basis of Recursion Iteration
Basic Recursion is the process of calling a function In iteration, there is a repeated execution of the
itself within its own code. set of instructions. In Iteration, loops are used to
execute the set of instructions repetitively until
the condition is false.
Syntax There is a termination condition is specified. The format of iteration includes initialization,
condition, and increment/decrement of a
variable.
Termination The termination condition is defined within the Here, the termination condition is defined in the
recursive function. definition of the loop.
Code size The code size in recursion is smaller than the The code size in iteration is larger than the code
code size in iteration. size in recursion.
Infinite If the recursive function does not meet to a Iteration will be infinite, if the control condition
termination condition, it leads to an infinite of the iteration statement never becomes false.
recursion. There is a chance of system crash in On infinite loop, it repeatedly used CPU cycles.
infinite recursion.
Applied It is always applied to functions. It is applied to loops.
Speed It is slower than iteration. It is faster than recursion.
Usage Recursion is generally used where there is no It is used when we have to balance the time
issue of time complexity, and code size requires complexity against a large code size.
being small.
Time complexity It has high time complexity. The time complexity in iteration is relatively
lower. We can calculate its time complexity by
finding the no. of cycles being repeated in a
loop.
Stack It has to update and maintain the stack. There is no utilization of stack.
Memory It uses more memory as compared to iteration. It uses less memory as compared to recursion.
Overhead There is an extensive overhead due to updating There is no overhead in iteration.
and maintaining the stack.
• Below are the detailed example to illustrate the difference between the two:
 
1. Time Complexity: Finding the Time complexity of Recursion is more difficult than that of Iteration. 
1. Recursion: Time complexity of recursion can be found by finding the value of the nth recursive call in terms of the previous calls. Thus, finding the destination case in
terms of the base case, and solving in terms of the base case gives us an idea of the time complexity of recursive equations. Please see  Solving Recurrences for more
details. 
 
2. Iteration: Time complexity of iteration can be found by finding the number of cycles being repeated inside the loop. 
 
2. Usage: Usage of either of these techniques is a trade-off between time complexity and size of code. If time complexity is the point of focus, and number of recursive calls would
be large, it is better to use iteration. However, if time complexity is not an issue and shortness of code is, recursion would be the way to go.
1. Recursion: Recursion involves calling the same function again, and hence, has a very small length of code. However, as we saw in the analysis, the time complexity of
recursion can get to be exponential when there are a considerable number of recursive calls. Hence, usage of recursion is advantageous in shorter code, but higher time
complexity. 
 
2. Iteration: Iteration is repetition of a block of code. This involves a larger size of code, but the time complexity is generally lesser than it is for recursion.  
 
3. Overhead: Recursion has a large amount of Overhead as compared to Iteration. 
1. Recursion: Recursion has the overhead of repeated function calls, that is due to repetitive calling of the same function, the time complexity of the code increases
manifold. 
 
2. Iteration: Iteration does not involve any such overhead. 
 
4. Infinite Repetition: Infinite Repetition in recursion can lead to CPU crash but in iteration, it will stop when memory is exhausted. 
1. Recursion: In Recursion, Infinite recursive calls may occur due to some mistake in specifying the base condition, which on never becoming false, keeps calling the
function, which may lead to system CPU crash. 
 
2. Iteration: Infinite iteration due to mistake in iterator assignment or increment, or in the terminating condition, will lead to infinite loops, which may or may not lead to
system errors, but will surely stop program execution any further. 
 
Convert Infix to Postfix
K+L-M*N+(0^P)*W/U/V*T+Q

You might also like