CS101 Introduction to computing
Recursion Memory LayoutRecursion, Memory Layout and
Problem Solving
A. Sahu and S. V .RaoDept of Comp. Sc. & Engg.Dept of Comp. Sc. & Engg.
Indian Institute of Technology Guwahati
Outline• Memory layout of C program• Recursive Function
–ExampleExample
• Problem Solving Example –Using modular functionsUsing recursive functions–Using recursive functions
–Using Arrays : Max, Part, Sort
Memory layout of C programy y p g
Dynamic memory allocationDynamic memory allocation• Reduce wastage of memory • Useful when data size is unknown before hand• Array Declaration int A[100];y
– Easy, Not to use pointer, small size, known before
[ ];
Easy, Not to use pointer, small size, known before
• Array Creation: Not easy use of pointer typecast lager size– Not easy, use of pointer, typecast, lager size, necessary size
Memory management C: APIs• Application program interfaces (APIs)A il bl f ti /API t• Available function/APIs to manage memory
• Create/allocate/reserve space– malloc : memory allocation– calloc : memory allocation + initialization to 0
• Move a reserved space to another location– realloc: move the space to another locationp
• Destroy/de‐allocate/free space• free:free:
Memory Allocation• Memory can be allocated • Declaring a variableDeclaring a variable
int A[100];
• Explicitly requesting space
i t *Aint *A;A=(int*)malloc(sizeof(int)*100);
Example: Dynamic Array Allocation
• Given N persons (with their IQ level) in orderN may be dynamic variable– N may be dynamic, variable
• A person decide He/She is intelligent or dumb • Decides locally:
– If his/her IQ level is greater than equal to average of IQ level of both neighbors
– Left neighbor and right neighbor
Example: Dynamic Array Allocationmain(){main(){
int *IQScore, *Intelligent, i, N; printf(“Input N:”); scanf(“%d”, &N); p t ( put : ); sca ( d , & );IQScore=(int*)malloc(N*sizeof(int));Intelligent =(int*)calloc(N*sizeof(int));for(i=0;i<N;i++) scanf(“%d”,&IQScore[i]);for(i=1;i<N-1;i++){
if(IQScore[i]> (IQScore[i 1]+IQScore[i+1])/2)if(IQScore[i]>=(IQScore[i-1]+IQScore[i+1])/2)Intelligent[i]=1; else Intelligent[i]=0;
printf(“ I am %d person %s\n”, i, Intelligent[i]?”YES”:”NO”);
}
free(IQScore); free(Intelligent);free(IQScore); free(Intelligent);}
Memory layout of C program• Program: Input, Output, ProcessingC d (I t ti ) D t (St k H )• Code (Instruction), Data (Stack, Heap)
• To store: Require memory– Input data, output data, intermediate data
• Memory can be allocated – Declaring a variable– Explicitly requesting space
int A[100];
p y q g p
int *A;A=(int*)malloc(sizeof(int)*100);
Memory layout of C programMemory layout of C program• Stack
automatic (default) local– automatic (default), local– Initialized/uninitialized
• Data
Stack
• Data– Global, static, externBSS Bl k S d b S b l
Heap
– BSS: Block Started by Symbol– BBS: Uninitialized Data Seg.
Data
BSSBSS
• Code : program instructions• Heap
Data
– malloc, calloc Code
Memory layout of C program
int A;Stack
int B=10;
main(){
Stack
(){
int Alocal;
int *p
Heap
BSSint *p;
p=(int*)malloc(40); Data
}
Code$gcc test.c$size a out$size a.outtext data bss dec hex filename1200 544 8 1752 6d8 a.out
Examples ofExamples of Modular code using Functions
Modular Code for : Xn
int PowXtoN(int n, int x){int n, x, P=1, PS=x;while(n > 0) {
#include <stdio.h>while(n > 0) {
if ((n%2)==1) P=P*PS;n=n/2; PS = PS* PS;
int GetNum();int PowXtoN(int n,int x);void DispRes(int,int,int);
}return P;}
p ( , , );
int main(){int X, N, Res; }}
X=GetNum();N=GetNum();R P Xt N(X N)
int GetANum(){ int N; printf(“Enter a Number:");
Res= PowXtonN(X,N);DispRes(Res,X,N);
return 0;
scanf(“%d", &N);return N; }
void DispRes(int Res, return 0;}
p ( ,int X, int N){
printf(“%d to power %d=%d”,X, N, Res); }
Modular C Code : Square root of a Positive NumberPositive Number
#include <stdio.h>float GetAccuracy();fl t G tP N ()
float SqRoot(float m, float e){float GetPosNum();
float SqRoot(float,float);
void DispRes(float,float);
float e){
float r1, r2;r1=m/2;
int main(){float a, e, Res;
r1=m/2; r2=r1;while(abs(r1-r2)>e){
r1 r2;a=GetPosNum();e=GetAccuracy();Res S R t(a e);
r1=r2;r2=(r1+m/r1)/2;
}ret rn 2Res= SqRoot(a,e);
DispRes(a, Res);
return 0;
return r2;}
return 0;}
You need to write code of other functions
Modular C Code : Factorial of a Number#i l d tdi h#include <stdio.h>
int GetNum();i t F t i l(i t A)
int Factorial(int n) {int Factorial(int A);void DispRes(int,int); int Prod=1,i;
for (i=1;i<=N;i++){int main(){int a, Res;
a GetNum();
Prod=Prod*i; }
a=GetNum();Res= Factorial(a);DispRes(a, Res);
return prod;}
return 0;}
You need to write code of other functions
Modular C Code : Reverse a Number#i l d tdi h#include <stdio.h>
int GetNum();i t R (i t A)
int Reverse(int n) {int Reverse(int A);
void DispRes(int,int); int RevNum=0, Rem;RevNum=0;
int main(){int a, Res;
a GetNum();
while(n != 0) {Rem = n%10;RevNum=RevNum*10+ Rem;
a=GetNum();Res= Reverse(a);DispRes(a, Res);
n=n/10;}
return RevNum;return 0;
} }
You need to write code of other functions
Modular C Code : Binary Search#i l d tdi h#include <stdio.h>int GetMinOfRange();int GetMaxOfRange();int GetUnknown();
int BinSrch(int Rmin, intRmax, int X){
int GetUnknown();int BinSrch(int,
int, int);
void DispRes(int);
while (Rmin<Rmax){mid=(Rmin+Rmax)/2;void DispRes(int);
int main(){int Min, Max, X, Res;
mid (Rmin+Rmax)/2;if(X==mid)return mid;if (X>mid)
R i id+1Min=GetMinOfRange();Max=GetMaxOfRange();X=GetUnknown();
Rmin=mid+1; else Rmax=mid;}();
Res=BinSrch(Min,Max,X)DispRes(Res); return 0;
return -1;}
}
You need to write code of other functions
Modular C Code : Nth Fibonacci #i l d tdi h#include <stdio.h>
int GetNum();i t Fib(i t N)
int Fib(int N) {
int Fib(int N);
void DispRes(int,int);int fnm2=0; fnm1=1; n=2;if(N<=1) return 1; while(n<=N){int main(){
int N, Res;
N GetNum();
while(n<=N){fn = fnm2 + fnm1;fnm2=fnm1; f 1 fN=GetNum();
Res= Fib(N);DispRes(N, Res);
fnm1=fn;n = n + 1;}
return 0;}
return fn;}
You need to write code of other functions
Modular C Code : GCD#i l d tdi h#include <stdio.h>
int GetA();int GetB();
int GCD(int n1, int n2) {int GetB();int GCD(int A, int B);
Void DisRes(int,int,int);while(!(n1==0|| n2==0)){
if (n1>n2) n1=n1%n2;int main(){int a, b, Res;
a GetA();
( )else n2=n2%n1;
}if (n1==0) return n2;a=GetA();
b=GetB();Res= GCD(a,b);DisRes(a b Res);
if (n1 0) return n2; else return n1;}
DisRes(a, b, Res);
return 0;} }
You need to write code of other functions
Modular Code Sin(x)#i l d tdi h#include <stdio.h>float GetX();float GetAccuracy();fl t Si XC l(fl t
float SinXCal(float x,
float acc){float SinXCal(float x,
float acc);
void DispRes(float,float);
int i=1;
float SinXVal=0,term=x;
while (term < acc) {p ( )
int main(){float X, acc, Res;
( ) {
i = i+2;term *= - x*x/(i*(i-1));Sin Val Sin Val+ term
X=GetX();acc=GetAccuracy();R Si XC l(X )
SinxVal= SinxVal+ term;
}
return SinXVal;Res= SinXCal(X,acc);DispRes(X, Res);
return 0;
}
return 0;}
You need to write code of other functions
Modular C Code : Value of PI#include <stdio.h>
int GetABigNumer();
double ValPI(int N){int M=0,i;int GetABigNumer();
double ValPI(int N);
void Di R (i t fl t)
double x,y,z,pi; for(i=0;i<N;i++){x=(double)rand()/RAND MAX;DispRes(int,float);
int main(){int N;
x (double)rand()/RAND_MAX;y=(double)rand()/RAND_MAX;z = x*x+y*y;if ( < 1) M++int N;
double Res; N=GetABigNumber();Res= ValPI(N);
if (z<=1) M++;}pi=4.0*(double)M/N;Res= ValPI(N);
DispRes(a, b, Res);
return 0;
return pi;}
;}
You need to write code of other functions
Modular C Code : Bisection Method#include <stdio.h>float GetMinOfInterVal();float GetMaxOfInterVal();fl t G tA ()
float F(float a){return a*a*a-2*a-5;
}float GetAccuracy();float F(float a);
float Bisection(float a,
float Bisection(float a,
float a, float acc){float F Fb F
}
float a, float acc)
void DispRes(float,float,float);int main(){
float Fa, Fb, Fx;Fa=F(a); Fb=F(b);x=a; x1=b;while( abs(x-x1)>accuracy) {
float a, b, acc,Res;a=GetMinOfInterVal();b=GetMaxOfInterVal();
G tA ()
while( abs(x x1)>accuracy) {x1=x; x=(a+b)/2; Fx=F(x);if(Fa*Fx<0) b=x;else a=x;
acc=GetAccuracy();Res= Bisection(a,b,acc);DispRes(a,b,Res); return 0;
( ) ; ;}
return x;
}return 0;}
}
You need to write code of other functions
RecursionsRecursions and
Recursive functions
Recursions: Recursive functions • Functions that call themselves• Can only solve a base case• Divide a problem up into
– What it can do– What it cannot do
• What it cannot do resembles original problem• The function launches a new copy of itself (recursion step) to solve what it cannot do
• Eventually base case gets solvedEventually base case gets solved– Gets plugged in, works its way up and solves whole problemp
Recursions: Recursive functions • Many Problem , we define the problem it self using recursive p gdefinition
• Solving them using recursion• Solving them using recursion – Easier to think and implement
• Example• Example – Fibonacci, GCD, Binary Search, calculation of Xn, Reversing numberReversing number
• Recursive Functions– Functions that call themselves (directly/indirectly)Functions that call themselves (directly/indirectly)– Can only solve a base case
Recursion Example: factorials5! 5 * 4 * 3 * 2 * 1• 5! = 5 * 4 * 3 * 2 * 1
• Notice that– 5! = 5 * 4!– 4! = 4 * 3! ...
• Can compute factorials recursively S l b ( ) h l• Solve base case (1! = 0! = 1) then plug in–2! = 2 * 1! = 2 * 1 = 2;–3! = 3 * 2! = 3 * 2 = 6;3! 3 2! 3 2 6;
Recursion vs Iteration• Repetition
– Iteration: explicit loopp p–Recursion: repeated function calls
• Termination• Termination– Iteration: loop condition fails–Recursion: base case recognized
• Both can have infinite loopsBoth can have infinite loops• Balance
–Choice between performance (iteration) and good software engineering (recursion)
Recursion Example: factorials• From Definition: but no terminationint Fact(int N){
return N * Fact (N-1);}
• With proper base case (termination
}
With proper base case (termination guaranteed )
int Fact (int N){if(N<=1) return 1; t N * F t (N 1)return N * Fact (N-1);
}
Factorial: Recursive call Fact(1);
Fact(3);
Fact(2);1
int Fact (int N){if(N<=1) return 1; return N*Fact(N-1);
Fact(4);
Fact(3);2
6( );}int main(){
int X;
24
120int X;X=fact(5);printf(“Fact of 5=%d \n”,X);
120
return 0;}
Nested Function Call• Nested Function call uses
– Stack to store the return address, return result and any other information
• Recursion– Stack grows as deepen the nested function call – Recursive call: Stack grows when it call next grecursive function
– All the local variable need to be put into stackp– Stack contains grows like this: Fib Example
• Main, Fib(5), Fib(4), Fib(3), Fib(2), Fib(1)
Recursion vs Iteration• Any problem that can be solved recursively –Can also be solved iteratively (non‐recursively)
• A recursive approach is normally chosen in preference – To an iterative approach when the recursive approach more naturally mirrors the problem
d l h– And results in a program that is easier to understand and debug
• Another reason to choose a recursive solution• Another reason to choose a recursive solution – An iterative solution may not be apparent
Recursion vs Iteration• Avoid using recursion in performance situations
– Recursive calls take time – And consume additional memory
• Common Error by programmer– Accidentally a non‐recursive function may call itself either directly, or indirectly through another function
• Functionalizing programs in a neat, hierarchical manner promotes good practice – More easier to program, test, debug, maintain, and evolve.
– But it has a price, A heavily functionalized program: makes potentially large numbers of function calls
Solving Recursive ProblemsSolving Recursive Problems• See recursive solutions as two sections:
–CurrentR t–Rest
N! = N * (N‐1)!7! 7 * 6!7! = 7 * 6! 7! = 7 * (6 * 5 * 4 * 3 * 2 * 1 * 1)
Factorial FunctionFactorial Function
int Fact (int N){if(N<=1) return 1; return N*Fact(N-1);
}
Factorial Functionif (1 == 1)
Factorial Function
return 1;else
return 1 * Fact(0);
if (2 == 1) return 1;
elsereturn 2 * Fact(1);
if (3 == 1) return 1;
elsereturn 3 * Fact(2);
main {X = Fact(3)
}
Tracing Details
1 A t l t t d1. Actual parameters stored on the stack
3 C t
5. Return value and release stack frame
int Fact (Num =3)if (3 = 1)
return 1;else
3. Create a new Stack Frame
elsereturn 3 * Fact(2);
}
2. Recursive call to Fact
4. Unfinished Business
Activation Stack for FactorialActivation Stack for Factorial
C ll th f ti X F t(5)Call the function: X= Fact(5);
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 3rd: N=3, Unfinished: 3*Fact(2)
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact. 4th: N=2, Unfinished: 2*Fact(1)
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 3rd: N=3, Unfinished: 3*Fact(2)
Fact. 4th: N 2, Unfinished: 2 Fact(1)
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact. 4th: N=2, Unfinished: 2*Fact(1)
Fact. 5th: N=1, Finished: returns 1
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 3rd: N=3, Unfinished: 3*Fact(2)
Fact. 4th: N 2, Unfinished: 2 Fact(1)
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact. 4th: N=2, Finished: returns 2*1
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 3rd: N=3, Unfinished: 3*Fact(2)
Fact. 4th: N 2, Finished: returns 2 1
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact 2nd: N 4 Unfinished: 4*Fact(3)
Fact. 3rd: N=3, Finished: returns 3*2
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Unfinished: 4*Fact(3)
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact 2nd: N 4 Finished: returns 4*6
Fact. 1st: N=5, Unfinished: 5*Fact(4)
Fact. 2nd: N=4, Finished: returns 4*6
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Fact. 1st: N=5, Finished: returns 5*24
Main Function: Unfinished: X = Fact (5);
Activation Stack for FactorialActivation Stack for Factorial
Main Function: finished: X = 120;
Recursive Function: XnRecursive Function: X• Xn = X * X(n‐1)
• When n <=1; Xn=X
• Power(base, exp)= base * Power(base, exp‐1);
int Power (int base, int exp){
Activations Stack ExampleRecursive Function: Xn
int Power (int base, int exp){if(exp <=0) return 1;return X *Power(base, exp‐1);
}}Power base = 3 exp = 0 Finished: 11
11
Power base = 3 exp = 2 3 *Power(3,1)
Power base = 3 exp = 1 3 *Power(3,0)1
333
Power base = 3 exp = 3 3 *Power(3,2)
Power base 3 exp 2 3 Power(3,1)
999
2727Power base = 3 exp = 4 3 *Power(3,3)27
2727
8181main: total = Power(3,4)Total =81
The nth power of X• Is there any better approach?• From basic algebrag
– if n is even == > Xn = Xn/2.Xn/2
– If n is odd and n=2m+1 ==> Xn= X2m+1= xm . xm . x • From this above fact, can we calculate Xn in fewer steps
int Pow (int X, int N){if(N <=0) return 1;if(N < 0) return 1;int Y=Pow(X,N/2);if(N %2==0) return Y *Y;l t X*Y*Yelse return X*Y*Y;
}
A More Complex Recursive FunctionFibonacci Number SequenceA More Complex Recursive Function
if n = 1, then Fib(n) = 1if n = 2, then Fib(n) = 1if n > 2, then Fib(n) = Fib(n‐2) + Fib(n‐1)
Numbers in the series:Numbers in the series:1, 1, 2, 3, 5, 8, 13, 21, 34, ...
Fibonacci Sequence FunctionFibonacci Sequence Function
int Fib (int n){int Fib (int n){if (n == 1) ||(n == 2)) return 1;return 1;
elsereturn Fib(n-2)+Fib(n-1);return Fib(n 2)+Fib(n 1);
}
main(){int answer; answer=fib(5);
}printf(“5 th Fib Num is %d”, answer);}
ThanksThanks