UNIT 5 STACK
Syllabus
Basic concept, stack Abstract Data Type,
Representation of Stacks Using Sequential
Organization, stack operations, Multiple Stacks,
Applications of Stack- Expression Evaluation and
Conversion, Polish notation and expression
conversion, Need for prefix and postfix expressions,
Postfix expression evaluation, Linked Stack and
Operations.
Recursion- concept, variants of recursion- direct,
indirect, tail and tree, backtracking algorithmic
strategy, use of stack in backtracking
S
t
a
c Outline
k
E
Sx
O
ta
p
am
ec
p
rk
la
et
a
is
o
n
a
sn
aA
n
D
d
T Definition of
I
Stack
m
Definition of stack
A stack is a linear data structure in which insertion and
deletion allowed only at the one end, called the top of the
stack.
For Example
Stack of Coin
Stack of Books
Stack of Ball with Jar
Cont..
We can add and delete an element only from one end
i.e. top
It is a homogeneous collection of item of any one data
type, arrange linearly and access from only one end
Stack is work on LIFO ( Last in First out) principle
Real time Examples
The Stack data structure is used by text editors for the undo or
redo operations, string reversal, and web browsers for page-
visited history.
Mobile Phone: Call log in mobiles uses the stack, to get a first-
person call log you have to scroll.
Tubewell Boring Machine: Tubewell boring machine use
stack to pull or push same as stack
Floors in a Building: A person is living on a top floor and
wants to go outside, he/she first need to land on the ground
floor.
Stack as an ADT
When we define a stack as an ADT ( or Abstract
Data Type) , then we are only interested in
knowing the stack operation from the user point of
view.
Primary opeations
push(value) - Inserting value or data into the
stack
Example:
Empty Stack
Top
Top is pointing to position 0 After Data
Inserted
into Stack
Cont..
pop() - Delete the last inserted value from the
Stack
Example POP(2)
Top
Top
Stack with Stack after
some data pop(2)
Secondary Operation
Top(): return the last element from stack
without removing it from stack.
Example
Cont..
isEmpty(): it return TRUE if the stack is empty,
else it return FALSE.
Example
Is these YES
stack is
Is these empty
NOPE
stack is
empty
When Stack is Empty
When Stack is said to empty then it does not
contain any element inside it. Whenever the
Stack is Empty the position of topmost element
is -1.
Cont..
Isfull():it return TRUE if the stack is full, else it
return FALSE.
Example
Is these
Is these YES
NOPE stack is full
stack is full
Underflow and Overflow
situation
Stack underflow happens when we try to pop (remove) an
item from the stack, when nothing is actually there to remove.
Stack underflow
POP()
Empty
Stack
Stack overflow happens when we try to push one more item
onto our stack than it can actually hold.
Stack Overflow
PUSH(15)
Stack become full
Stack Implementation
A stack is a linear data structure in which insertion and
deletion allowed only at the one end, called the top of the
stack.
As stack is linear data structure, we can implement it using
array or linked list.
Array Implementation
Logical representation of array
Stack_arr
1-D array is used to hold the element of the stack.
As we know that stack is implemented using array so insertion and
deletion can done any where but we want that stack_arr[] behave like
stack.
Hence insertion and deletion operation must be performed by one end.
To do this we used “top” variable in implementation. Which keep index
of last inserted data in array.
Cont…
To indicate that stack is empty, we will put -1 in
variable top.
For push operation in stack:
First top is incremented by 1.
New element is pushed at the position top.
For pop operation in stack
The element at the position of top is deleted (logically) or
stored in another variable
Top is decremented by 1
Flow to implement stack
using array
Example
Before implementing actual operations, first follow
the below steps to create an empty stack.
Step 1 - Include all the header files which are used
in the program and define a constant 'SIZE' with
specific value.
#include <stdio.h>
#define size 10
Cont..
Step 2 - Declare all 1. void push(int);
the functions used in 2. void pop();
stack implementation. 3. void display();
Cont..
Step 2 - Declare all 1. int top, stack_element[size];
the functions used in 2. void push(int);
stack implementation. 3. void pop();
4. void display();
Step 3 - Create a one
dimensional array with
fixed size (int
stack[SIZE])
Cont..
Step 2 - Declare all 1. int top, stack_element[size];
the functions used in 2. top=-1;
stack implementation. 3. void push(int);
4. void pop();
5. void display();
Step 3 - Create a one
dimensional array with
fixed size (int
stack[SIZE])
Step 4 - Define a integer
variable 'top' and initialize
with '-1'. (int top = -1)
Cont..
Step 5 - In main method, display menu with list
of operations and make suitable function calls to
perform operation selected by the user on the
stack.
Stack_main
Step 6- define the function i.e push(), pop() and
display()
Push operation
Use the following steps to push an void stack_operation::push(int item)
element on to the stack {
if(top==size-1)
Step 1 - Check {
whether stack is FULL or not. (top cout<<"\n Stack is full";
== SIZE-1) }
else
Step 2 - If it is FULL, then
{
display "Stack is overflow!!! stack_element[++top]=item;
Insertion is not possible!!!" and cout<<"\n Item Pushed";
terminate the function. }
display();
Step 3 - If it is NOT FULL, then }
increment top value by one (top+
+) and
set stack[top] to value (stack[top] =
value).
Pop operation
We can use the following steps to void stack_operation::pop()
pop an element from the stack... {
if(top<0)
{
Step 1 - Check
cout<<"\n Stack is in
whether stack is EMPTY. (top ==
Underflow";
-1)
}
else
Step 2 - If it is EMPTY, then {
display "Stack is EMPTY!!! cout<<"\n Itemed
Deletion is not possible!!!" and Popped"<<stack_element[top];
terminate the function. top--;
}
Step 3 - If it is NOT EMPTY, then display();
delete stack[top] and }
decrement top value by one
Display operation
We can use the following steps to void stack_operation::display()
display the elements of a stack... {
Step 1 - Check if(top==-1)
whether stack is EMPTY. (top ==
-1) cout<<"\nStack is Empty!!!";
Step 2 - If it is EMPTY, then else
display "Stack is EMPTY!!!" and {
terminate the function. cout<<"\nStack elements
Step 3 - If it is NOT EMPTY, then are:\n";
define a variable 'i' and initialize for(int i=0;i<=top;i++)
with top. Display stack[i] value
and decrement i value by one cout<<stack_element[i]
(i--). <<"\t";
Step 3 - Repeat above step }
until i value becomes '0'. }
Complexity
Time complexity for each Operations like insertion
or deletion in a stack take constant time i.e. O(1).
Space complexity for each operation in a stack
is O(1), as no extra space is required for any
operation.
Execution or Program
Run the code
https://www.onlinegdb.com/online_c++_compiler
Stack Operation Code
STACK APPLICATIONS
Stack Application
Expression Evaluation
INFIX Expression
PREFIX Expression
POSTFIX Expression
Infix, Postfix and Prefix notations are three different but
equivalent ways of writing expressions.
Recursion Handling
Parenthesis Handling eg. {}, [], ()
Backtracking
Evaluation of Infix
Infix notation: X + Y
Operators are written in-between their operands.
When evaluating an infix expression, we need to
use the precedence of operators
Evaluation is done from left to right but operator
precedence must be considered.
Example
Consider the equation
X+Y*Z
where X=2, Y=3 and Z=6
X+Y*Z
2+3*6
2+18
20
Evaluation of prefix
Operators are written before their operands.
The expressions given above are equivalent
to / * A + B C D
These expression evaluate from right to left and
perform the operations.
Evaluation is done from right to left but it free from
operator precedence
Example
Consider the equation
+X*YZ
where X=2, Y=3 and Z=6
+X*YZ
+2*36
place a bracket from right to left
+2 18
20
Evaluation of postfix
Operators are written after their operands.
The postfix expression look like A B C + * D /
Evaluation is done from left to right but free
from operator precedence.
Postfix Evaluation with a Stack
Evaluation of postfix expressions makes use of an
operand stack.
Algorithm Pseudocode:
push all operands on stack until an operator is
encountered
when an operator is encountered pop the last two
operands off the stack and apply the operation - order of
operands is important
push the result of the operation back on the stack to be
used as an operand later
when end of expression is reached one operand remains
on the stack - it is the final result
Example
For example, consider the evaluation of the
following postfix expression using stacks:
abc+d*f/-
where, a=6, b=3, c-6, d=5, f=9
The expression is evaluated as follows:
636+5*9/-
636+5*9/-
636+5*9/-
636+5*9/-
Step Wise Evaluation
Examples
1)AB+C*D(if A=2,B=3,C=4,D=5)( assume +
after D)
(2)562+*124/-
(3)ABC^/DE*+AC*-(A=27,B=3,C=2,D=3,E=17)
(4)76 + 4 * 410 - ^ 5 +
(5) 75 – 9 2 / * (ANS: 9.00)
Agenda
Expression Conversion using stack
Expression Conversion
Expression can be represented in Infix, Prefix
and Postfix.
Conversion of the expression to another form
may be accomplished using stack.
Prerequisite for conversion is priority of the
operators
Types of conversion
Infix to postfix conversion
Infix to prefix conversion
Prefix to postfix conversion
Prefix to infix conversion
Postfix to prefix conversion
Postfix to infix conversion
Infix to postfix
conversion
Scan the Infix expression left to right
If the character x is an operand
Output the character into the Postfix Expression
If the character x is a left or right parenthesis
If the character is “(“
Push it into the stack
if the character is “)”
Repeatedly pop and output all the
operators/characters until “(“ is popped from the
stack.
If the character x is a is a regular operator
Step 1: Check the character y currently at the top of
the stack.
Step 2: If Stack is empty or y=‘(‘ or y is an operator of
lower precedence than x, then push x into stack.
Step 3: If y is an operator of higher or equal
precedence than x, then pop and output y and push x
into the stack.
When all characters in infix expression are processed repeatedly pop the
Infix to postfix conversion
Stack
Infix Expression
(a+b-c)*d–(e+f)
Postfix Expression
Infix to postfix conversion
Stack
Infix Expression
a+b-c)*d–(e+f)
Postfix Expression
(
Infix to postfix conversion
Stack
Infix Expression
+b-c)*d–(e+f)
Postfix Expression
a
(
Infix to postfix conversion
Stack
Infix Expression
b-c)*d–(e+f)
Postfix Expression
a
+
(
Infix to postfix conversion
Stack
Infix Expression
-c)*d–(e+f)
Postfix Expression
ab
+
(
Infix to postfix conversion
Stack
Infix Expression
c)*d–(e+f)
Postfix Expression
ab+
-
(
Infix to postfix conversion
Stack
Infix Expression
)*d–(e+f)
Postfix Expression
ab+c
-
(
Infix to postfix conversion
Stack
Infix Expression
*d–(e+f)
Postfix Expression
ab+c-
Infix to postfix conversion
Stack
Infix Expression
d–(e+f)
Postfix Expression
ab+c-
*
Infix to postfix conversion
Stack
Infix Expression
–(e+f)
Postfix Expression
ab+c-d
*
Infix to postfix conversion
Stack
Infix Expression
(e+f)
Postfix Expression
ab+c–d*
-
Infix to postfix conversion
Stack
Infix Expression
e+f)
Postfix Expression
ab+c–d*
(
-
Infix to postfix conversion
Stack
Infix Expression
+f)
Postfix Expression
ab+c–d*e
(
-
Infix to postfix conversion
Stack
Infix Expression
f)
Postfix Expression
+ ab+c–d*e
(
-
Infix to postfix conversion
Stack
Infix Expression
)
Postfix Expression
+ ab+c–d*ef
(
-
Infix to postfix conversion
Stack
Infix Expression
Postfix Expression
ab+c–d*ef+
-
Infix to postfix conversion
Stack
Infix Expression
Postfix Expression
ab+c–d*ef+-
Example
Infix to prefix conversion
Expression = (A+B^C)*D+E^5
Step 1. Reverse the infix expression.
5^E+D*)C^B+A(
Step 2. Make Every '(' as ')' and every ')' as '('
5^E+D*(C^B+A)
Step 3. Convert expression to postfix form. Using infix to
postfix algorithm A+(B*C-(D/E-F)*G)*H
Step 4. Reverse the expression to get prefix answer
+*+A^BCD^E5
Flow chart for conversion
Convert Prefix to Infix Expression
Algorithm:
Iterate the given expression from right to left (in reverse
order), one character at a time
If character is operand, push it to stack.
If character is operator,
pop operand from stack, say it’s s1.
pop operand from stack, say it’s s2.
perform (s1 operator s2) and push it to stack. Apply () to operation
and then push into stack
Once the expression iteration is completed, initialize result
string and pop out from stack and add it to result.
Return the result.
Examples
Input: Prefix expression: + A B
Output: Infix expression- (A + B)
Input: Prefix expression: *-A/BC-/AKL
Output: Infix expression: ((A-(B/C))*((A/K)-
L))
Prefix to postfix
Example
Input: Prefix expression: + A B
Output: Postfix expression: A B +
Input: Prefix expression: *-A/BC-/AKL
Output: Postfix expression: ABC/-AK/L-*
Convert Prefix to Infix Expression
Algorithm:
Iterate the given expression from right to left (in reverse
order), one character at a time
If character is operand, push it to stack.
If character is operator,
pop operand from stack, say it’s s1.
pop operand from stack, say it’s s2.
perform (s1 operator s2) and push it to stack. Apply () to operation
and then push into stack
Once the expression iteration is completed, initialize result
string and pop out from stack and add it to result.
Return the result.
Example
Input: Prefix expression: + A B
Output: Infix expression- (A + B)
Input: Prefix expression: *-A/BC-/AKL
Output: Infix expression: ((A-(B/C))*((A/K)-
L))
Convert Postfix to Prefix Expression
Algorithm:
Iterate the given expression from left to right, one character at
a time
If the character is operand, push it to stack.
If the character is operator,
Pop operand from the stack, say it’s s1.
Pop operand from the stack, say it’s s2.
perform (operator s2 s1) and push it to stack.
Once the expression iteration is completed, initialize the result
string and pop out from the stack and add it to the result.
Return the result.
Example
Input: Postfix expression: A B +
Output: Prefix expression- + A B
Input: Postfix expression: ABC/-AK/L-*
Output: Infix expression: *-A/BC-/AKL
Convert Postfix to Infix Expression
Algorithm:
Iterate the given expression from left to right, one character at
a time
If a character is operand, push it to stack.
If a character is an operator,
pop operand from the stack, say it’s s1.
pop operand from the stack, say it’s s2.
perform (s2 operator s1) and push it to stack.
Once the expression iteration is completed, initialize the result
string and pop out from the stack and add it to the result.
Return the result.
Example
Input: Postfix expression: A B +
Output: Infix expression- (A + B)
Input: Postfix expression: ABC/-AK/L-*
Output: Infix expression: ((A-(B/C))*((A/K)-
L))
Polish notation
Polish notation was invented in 1924 by Jan Lukasiewicz, a Polish
logician and philosopher, in order to simplify sentential logic.
The idea is simply to have a parenthesis-free notation that makes
each equation shorter and easier to parse in terms of defining the
evaluation priority of the operators.
Example:
Infix notation with parenthesis: (3 + 2) * (5 – 1)
Polish notation: * + 3 2 – 5 1
When used as the syntax for programming language interpreters,
Polish notation can be readily parsed into an abstract syntax tree
and stored in a stack
Postfix Notation This notation style is known as Reversed Polish
Notation.
RECURSION
Recursion
In C++, any function can call another function.
A function can even call itself.
When a function call itself, it is making a recursive call.
Recursive Call
A function call in which the function being called is the same as the
one making the call.
Recursion is a powerful technique that can be used in the place
of iteration(looping).
Recursion
Recursion is a programming technique in which procedures and
functions call themselves.
recursion works
The recursion function will continue
looping until a given recursive
condition is met.
The process of recursion continues
until we find the final solution to a
given problem.
Every time a part of the solution is
found, it is stored in the form of
a stack data structure in the
memory and at the end, it’s popped
out to get the final solution.
Types of recursion
Direct Recursion
Indirect Recursion
Tail Recursion
Direct Recursion
If a function calls itself, it’s known as direct recursion.
This results in a one-step recursive call: the function makes a
recursive call inside its own function body.
Below is an example of a direct recursive function that
computes the square of a number:
1. #include <iostream>
2. using namespace std;
3. // recursive function to calculate square of a number
4. int square(int x)
5. { int main() {
6. // base case // implementation of square function
7. if (x == 0) int input=30;
cout << input<<"^2 = "<<square(input);
8. {
return 0;
9. return x; }
10. }
11. // recursive case
12. else
13. {
14. return square(x-1) + (2*x) - 1;
15. }
16. }
Indirect Recursion
If the function f1 calls another function f2 and f2 calls f1 then
it is indirect recursion (or mutual recursion).
This is a two-step recursive call: the function calls another
function to make a recursive call.
Note: For indirect recursion, both the functions need to be
declared before they are defined.
Below is an implementation of indirect recursion that prints
the first 20 integers:
1. #include <iostream>
void foo2()
2. using namespace std;
{
3. int n=0;
if (n <= 20)
{
4. // declaring functions
cout<<n<<" "; // prints n
5. void foo1(void);
n++; // increments n by 1
6. void foo2(void);
foo1(); // calls foo1()
}
7. // defining recursive functions
else
8. void foo1()
return;
9. {
}
10. if (n <= 20)
11. {
// Driver Program
12. cout<<n<<" "; // prints n
int main(void)
13. n++; // increments n by 1
{
14. foo2(); // calls foo2()
foo1();
15. }
return 0;
16. else
}
17. return;
18. }
Direct and Indirect recursion difference
Tail recursion
A recursive function is called tail recursive if only one recursive call appears
in the function and that recursive call is the last statement in the function
body.
This approach provides decreased stack implementation time and gives
faster execution.
Smart compilers can detect tail recursion and convert it to iterative to
optimize code
node* find_value(node *temp, int value)
{
if (temp == NULL)
return NULL;
if (temp->data == value)
return temp;
return find_value(temp->next, value);
}
Recursion Tree
Recursion Tree Method is a pictorial representation of an
iteration method which is in the form of a tree where at each
level nodes are expanded.
In general, we consider the second term in recurrence as root.
It is useful when the divide & Conquer algorithm is used.
It is sometimes difficult to come up with a good guess. In
Recursion tree, each root and child represents the cost of a single
subproblem.
We sum the costs within each of the levels of the tree to obtain a
set of pre-level costs and then sum all pre-level costs to
determine the total cost of all levels of the recursion.
A Recursion Tree is best used to generate a good guess, which
can be verified by the Substitution Method.
https://www.javatpoint.com/daa-recursion-tre
e-method
Backtracking Algorithm
Backtracking can be defined as a general algorithmic technique that
considers searching every possible combination in order to solve a
computational problem
Backtracking is an algorithmic technique for solving problems
recursively by trying to build a solution incrementally, one piece at
a time, removing those solutions that fail to satisfy the constraints
of the problem at any point of time (by time, here, is referred to the
time elapsed till reaching any level of the search tree).
It uses recursive calling to find a solution set by building a
solution step by step, increasing levels with time.
A backtracking algorithm uses the depth-first search method.
Types of Backtracking Algorithm
There are three types of problems in backtracking
Decision Problem – In this, we search for a feasible solution.
Optimization Problem – In this, we search for the best solution.
Enumeration Problem – In this, we find all feasible solutions.
Example
simple example here in order to explain the theory behind a
backtracking process. We want to arrange the three letters a, b, c
in such a way that c cannot be beside a.
According to the backtracking, first, we’ll build a state-space tree.
We’ll find all the possible
solutions and check them
with the given constraint.
We’ll only keep those
solutions that satisfy the
given constraint:
Cont..
The possible solutions of the problems would
be:
Nevertheless, the valid solutions to this problem
would be the ones that satisfy the constraint,
which keeps only in the final solution
set.
Backtracking example
For example, consider the SudoKo solving Problem, we try
filling digits one by one.
Whenever we find that current digit
cannot lead to a solution, we remove it
(backtrack) and try next digit.
This is better than naive approach
(generating all possible combinations
of digits and then trying every
combination one by one) as it drops a
set of permutations whenever it
backtracks.
Cont..
At a point where a choice is made, we may discover
that the choice leads to a dead-end. We want to
retrace back to that decision point and then try the
other (next) alternative.
Again, stacks can be used as part of the solution.
Recursion is another, typically more favored,
solution, which is actually implemented by a stack.
Queen Problem
Tower of Hanoi
Recursion Vs. Backtracking
SPPU Question Apr 23, Oct
22