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

Stack and Recursion

Chapter 2 discusses stacks and recursion, defining a stack as a LIFO data structure with operations like push and pop. It also covers the applications of stacks in expression conversion and recursion's role in algorithms, including factorial and Fibonacci calculations. The chapter highlights the advantages and disadvantages of recursion, emphasizing its clarity and efficiency in certain contexts while noting its potential inefficiencies.

Uploaded by

ak1990074
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Stack and Recursion

Chapter 2 discusses stacks and recursion, defining a stack as a LIFO data structure with operations like push and pop. It also covers the applications of stacks in expression conversion and recursion's role in algorithms, including factorial and Fibonacci calculations. The chapter highlights the advantages and disadvantages of recursion, emphasizing its clarity and efficiency in certain contexts while noting its potential inefficiencies.

Uploaded by

ak1990074
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Chapter 2:Stack and Recursion

Er.Sharad Neupane
Lecturer, Jankapur Engineering
College
Tathali,Bhaktapur
Definition of stack and its operations:
A stack is a data structure that works on LIFO(Last In First Out) principle
i.e. the lastly inserted element is first to be deleted from the stack. In
stack the insertion and deletion of the element can be done only from one
end called the top of the stack.
The insertion of element into the stack is called push operation and the
deletion of an element from the stack is called as pop operation. These
are the primitive operations performed in the stack.
9

Condition for stack full: 8 8


if(top= =size-1)
stack is full 7 7 7
Condition for stack
empty:
if(top = = -1) Top= -1
stack is empty
Fig: Push operation in stack

8 8

7 7 7

Top= -1
Fig: Pop operation from stack
Operations on stack:
Following are the different operations that can be performed on stack.
1)Create an empty stack.
2)IsFull:This operation allows us to check whether the stack is full or not.
3)IsEmpty:This operation allows us to check whether the stack is empty
or not.
4)Push:This operation allows us to insert a new item into the stack.
5)Pop:This operation allows us to delete the top element from the stack.
6)Print the entire stack.
Stack as an ADT:(Imp)
Data type is the collection of the values and the operations that can be performed on those set of
values. An ADT is the mathematical model that contains set of values and the function(operations)
that operates on those values without specifying the detail of those functions. The specification of
stack ADT is given below.
Abstract Data Type Stack
{
Finite collection of zero or more elements. //Value definition
Operations:(Operator Definition):
1.Create an empty stack(s):
Create stack s which is initially an empty stack.
2.IsFull(s):Determine whether the stack s is full or not. Return true if s is full otherwise return
false.
3.Is Empty(s):Determine whether the stack is empty or not. Return true is s is empty otherwise
return false.
4.Push(s,x):Push element x into the stack if and only if stack is not full.
5.Pop(s):Remove the top element from the stack if and only if stack in not empty.
6.Traverse(s):Read an entire stack to display the content of the stack s.
}
Algorithm for Push Operations in to the stack:
1.Check whether the stack is full or not(i.e.top==maxsize -1 or not)
2.If true
Display stack is Full
3.Else
a.Increment the top of the stack by one.
b.Push an element in to the top
4.For next push operation go to step 1.
Algorithm for Pop operations from the stack:
1.Check whether the stack is empty or not(i.e.top= =-1 or not)
2.If true
a.Display stack is empty
b.Exit
3.Else
a.Remove the top element from the stack.
b.Decrease the top by 1.
c.Return top element
4.For next pop operation go to step 1.
Stack Applications:
There are various applications of stack and they are:
1)Reversing the string
2)Balancing expressions
3)Infix expression to postfix expression conversion
4)Infix expression to prefix expression conversion.
5)Evaluation of a postfix expression.
Infix Expression to postfix Expression conversion:(Imp)
Any arithmetic expression can be represented in three different ways:Infix,Prefix
and postfix.
1.Infix Expression:
It is the traditional way of writing arithmetic expression where an operator is placed
in between its two operands that means <operand1 operator operand2>.Example
a+b,a-b,a/b,a%b etc.
2.Prefix Expression:
In prefix notation, an operator is placed before its two operands that means
<operator operand1 operand2>.Example +ab,-ab,/ab,%ab etc.
3.Postfix Expression:
In postfix expression, an operator is placed after the operand that means <operand1
operand2 operator. Example ab+,ab-,ab/,ab% etc.
Examples

Infix Postfix

A+B AB +

A+B–C AB + C -

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

A – B / (C * D $ E) ABCDE $ * / -
Note: Precedence of operators ^($),/,*,+, -
+ and – has same precedence
/ and * has same precedence
Examples:
->20+5-4=25-4=21

->Also,20+5-4=20+1=21

->20*30/10=20*3=60

->Also, 20*30/10=600/10=60
Algorithm for conversion from infix expression to postfix expression(Imp)
1.Scan one character at a time from left to right
2.Repeat while there is a data.
a.If scan character is ‘(‘ then push it in to the stack
b.If scan character is operand then append(add) to the postfix string.
c.If scan character is operator
i)If stack is empty then push it in to the stack
ii)If there is ‘(‘ in the top of the stack, push scanned operator in to the stack.
iii)If the precedence of scanned operator is higher than the operator on the
top of the stack, push that scanned operator in to the stack.
iv)If the precedence of scanned operator is less than or equal to the operator
on the top of the stack, pop the operator from the stack and append(add) to
the postfix string and then push the scanned operator in to the stack.
d.If the scanned character is ‘)’ then pop and append(add) the operator(s) to the
postfix string from the stack until ‘(‘ is found and ignore both of them.
3.Pop and append the characters to the postfix string until the stack is empty.
Algorithm for conversion from infix expression to the prefix expression:(Imp)
1)Reverse the given expression
2)Scan one character at a time from left to right.
3)Repeat while there is a data
a.If scanned character is ‘)’ then push it in to the stack
b.If scanned character is operand then append to the output string.
c.If scanned character is operator
i)If stack is empty push it in to the stack
ii)If there is ‘)’ at the top of the stack then push the scanned operator in to the
stack
iii)If the precedence of the scanned operator is higher or equal to the precedence of
the operator on the top of the stack, push it in to the stack
iv)If the precedence of the scanned operator is less than that of the operator on
the top of the stack then pop and append the operator from the top of the stack
to the output string and then push the scanned operator in to the stack.
d.If scanned operator is ‘(‘ then pop the operator(s) from the top of the stack and
add them to the output string until ‘)’ is found and ignore both of them.
e.Pop the remaining characters(symbols) from the stack and add(append) to the
output string
4.Reverse the output string to get the required prefix expression.
Example

Infix Prefix

A+B + AB

A+B–C - + ABC

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

A – B / (C * D $ E) - A / B * C $ DE
3

By reversing this output string we get required prefix


expression:
++-+KL×MN×//×^OPWUVTQ
Recursion:
-Recursion is a method to define something in terms of itself. Recursion
makes algorithms and its implementation more compact and simple.
Every recursive process consists of two parts:
1)A smallest, base case that is processed without recursion.
2)A general method that reduces a particular case to one or more of the
smaller cases.
A function that calls itself is said to be the recursive function. Recursion
is one of the most powerful programming tool.
Recursion vs Iteration:(Imp)
• Iteration
-As long as the condition is true the loop body is executed i.e. set of instructions
is repeatedly executed.
-When the loop body has been executed for the last time, the loop completely
terminates.
-It is used for loops and has larger code size.
-It has relatively lower time complexity.
• Recursion
-As long as the recursion condition is true the method is called again
-When the base case has been reached, no further recursion occurs however, all
recursive calls then unfold backwards, possibly leading to the execution of
further code
-It is used for functions and has smaller code size.
-It has very high time complexity.
Applications of Recursion:
-Recursion is useful for the definition of mathematical functions and also used in
game and puzzle solving.
-The most important data structure ‘tree’ doesnot exist without recursion.
-It is the backbone of AI
-Many of the well known sorting algorithms like quick sort,merge sort uses the
concept of recursion.
-It is the backbone for searching.
Factorial of a number:
For a positive integer n, the factorial of n is defined as the product of all integers between
n and 1 and both inclusive.
-In mathematics, n factorial is denoted by n!
Recursive Definition for factorial of a given number:
• n! = 1 if n = 0
n! = n * (n – 1)! if n > 0
• Hence,
0! = 1
1! = 1 * 0!
2! = 2 * 1!
3! = 3 * 2!
4! = 4 * 3!
A definition that defines an object in terms of simpler case of itself is called a
recursive definition
Evaluating Factorials for given numbers from Recursive Definition:
• From definition,
1. 5! = 5 * 4!
2. 4! = 4 * 3!
3. 3! = 3 * 2!
4. 2! = 2 * 1!
5. 1! = 1 * 0!
6. 0! = 1
• Each case is reduced to a simpler case until we reach the case of 0!, which is
defined directly as 1
• In line 6, we have evaluated factorial directly, so we backtrack from line 6 to 1,
returning the value computed in one line to evaluate the result of the previous line
Recursive definition for Fibonacci Numbers
• fib (n) = n if n = 0 or n = 1
fib (n) = fib (n – 1 ) + fib (n – 2) if n >=2

• Evaluate fib (5)

= fib (4) + fib (3)


= (fib (3) + fib (2)) + (fib (2) + fib (1))
= ((fib (2) + fib (1)) + (fib (1) + fib (0))) + ((fib (1) + fib (0)) + 1)
= (((fib (1) + fib (0)) + 1) + (1+0)) + ((1+0) + 1)
= (((1 + 0) + 1) + (1)) + ((1) + 1)
= (((1) + 1) + (1)) + ((1) + 1)
=5
Recursion and Stack:(Recursive function and use of stack):(Imp)
C allows to write functions that call themselves. Such functions are called recursive.
Consider the following which calculates the factorial of a given number n.
int fact(int n)
{
int x, y, prod;
if (n == 0) /* base case */
prod = 1;
else {
x = n-1;
y = fact(x); /* recursive call */
prod = n * y;
}
return prod;
}
Illustration of above recursive function can be shown as below
using the stack

3 2 * *
4 3 * * 4 3 * *
n x y prod n x y prod n x y prod

Initially fact(4) fact(3)


0 * * 1
1 0 * * 1 0 * *
2 1 * * 2 1 * * 2 1 * *
3 2 * * 3 2 * * 3 2 * *
4 3 * * 4 3 * * 4 3 * *
n x y prod n x y prod n x y prod

fact(2) fact(1) fact(0)


1 0 1 1
2 1 * * 2 1 1 2
3 2 * * 3 2 * * 3 2 2 6
4 3 * * 4 3 * * 4 3 * *
n x y prod n x y prod n x y prod

fact(1) fact(2) fact(3)

y = fact(0) y = fact(1) y = fact(2)


prod = n * y prod = n * y prod = n * y
4 3 6 24
n x y prod

fact(4)

y= fact(3)
prod = n * y
The Factorial Function Rewritten

int fact(int n)
{
if (n == 0)
return 1;
else
return n * fact(n-1);
}
The Fibonacci Function

int fib(int n)
{
int a, b, sum;
if (n == 0 || n == 1)
return n;
else
{
a = fib(n – 1);
b = fib(n – 2);
sum = a + b;
return sum;
}
}
Tower Of Hanoi(TOH) Problem(Imp):
 Three pegs A, B and C exists.
 Disks of different diameters are placed on peg A and larger disk is always below a
smaller disk.
 The objective is to move the disks to peg C using peg B as auxiliary
a) Only the top disk on any peg may be moved to any other peg.
b) A larger disk may never rest on a smaller one.
The idea:
The idea that gives a solution is to concentrate our attention not on the first step(which
must be to move the top disk somewhere) but rather on the hardest step i.e. moving the
bottom disk.
There is no way to reach the bottom disk until all the disks above the bottom have been
moved and furthermore they must all be on peg B so that we can move the bottom disk
from peg A to peg C.
Note that the total no. of steps required to solve the TOH problems containing n disks is
given by 2n - 1
A B C

A B C
A B C

A B C
Algorithm to move n disks from A to C using B as a auxiliary(Imp):
1. If n==1 move the single disk from A to C and stop.
2. Move the top (n-1)disks recursively from A to B using C as auxiliary.
3.Move the nth disk from A to C.
4.Move the (n-1) disks recursively from B to C using A as auxiliary.
Recursion Tree:(Imp)
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.

Let there are three pegs A,B and C.Recursion tree for three discs is as shown in the
figure below.
Recursion Tree for TOH containing 4 disks(Imp)

L C R
Advantages and Disadvantages of Recursion:(Imp)
Advantages:
1)Reduce unnecessary calling of functions.
2)Adds clarity and reduces the time needed to write and debug code.
3)Better at tree traversal.
Disadvantages:
1)Less efficient.
2)Not all problems have recursive solution.
3)Makes code smaller to understand but complex for computer.
4)Recursive function are generally slower than non-recursive
5)Requires a lot of memory to hold intermediate results on the system
stack.
Types of Recursion:
Tail and non-tail recursion:(Imp)
In tail recursion, the recursive call is the last thing executed in the function. There is nothing left to do after coming
back from the recursive call.
Example:
#include<iostream>
#include<cstdlib>
using namespace std;
void printN(int n)
{
if(n<0)
{
exit(0);
}
cout<<n<<“ “;
printN(n-1);
}
int main( )
{
printN(10);
return 0;
}
Output:
10 9 8 7 6 5 4 3 2 1 0
Non tail recursion:
In non-tail recursion, the function does more work after the recursive call
returns. The tail recursion is better than the non tail recursion as there is
no task left after the recursive call so it will be easier for the compiler to
optimize the code.
Example:
int fact (int n)
{
if(n==0)
return 1;
else
return n * fact(n-1);
}
Explanation:
After the recursive call the function still needs to multiply by n.This
build up stack frames and is less efficient.

You might also like