You are on page 1of 42

Recursion & 1D

arrays

19CSE102 Computer Programming


A quick overview of functions in C

Function
Definition

Function call
How are function calls implemented?
• The following applies in general, the implementation details of function call
• The system maintains a stack in memory
• Stack is a last-in first-out structure
• Two operations on stack, push and pop
• This function call mechanism is depicted in the following figure.

• Note that the red arrow shows the function call and return.
• Whenever there is a function call, the activation record gets pushed into
the stack
• Activation record consists of the return address in the calling
program, the return value from the function, and the local variables
inside the function

• Pop activation record, whenever the function returns

• Activation record looks like:


Local
Variables
Return Value
Return Addr
int main()
{ int gcd (int x, int y)
…….. {
x = gcd (a, b); ……..
…….. ……..
} return (result);
}

Local
Activation Variables
record Return Value
STACK

Return Addr

Before call After call After return


Recursion
• A process by which a function calls itself repeatedly
• Either directly.
• X calls X
• Or cyclically in a chain.
• X calls Y, and Y calls X

• Used for repetitive computations in which each action is stated in


terms of a previous result
fact(n) = n * fact (n-1)
Contd.
• For a problem to be written in recursive form, two conditions are to
be satisfied:
• It should be possible to express the problem in recursive form
• Solution of the problem in terms of solution of the same problem on smaller sized data
• The problem statement must include a stopping condition

fact(n) = 1, if n = 0 Stopping condition


= n * fact(n-1), if n > 0 Recursive definition
• Examples:

• Factorial:
fact(0) = 1
fact(n) = n * fact(n-1), if n > 0

• Fibonacci series (0,1,1,2,3,5,8,13,21,….)


fib (0) = 0
fib (1) = 1
fib (n) = fib (n-1) + fib (n-2), if n > 1
Factorial

long int fact (int n)


{
if (n == 0)
return 1;
else
return (n * fact(n-1));
}
Factorial Execution

long int fact (int n)


{
if (n = = 0) return 1;
else return (n * fact(n-1));
}
Factorial Execution
fact(4)

long int fact (int n)


{
if (n = = 0) return 1;
else return (n * fact(n-1));
}
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

long int fact (int n)


{
if (n = = 0) return (1);
else return (n * fact(n-1));
}
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2));

long int fact (int n)


{
if (n = = 0) return (1);
else return (n * fact(n-1));
}
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2));

if (2 = = 0) return (1);
else return (2 * fact(1));
long int fact (int n)
{
if (n = = 0) return (1);
else return (n * fact(n-1));
}
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2));

if (2 = = 0) return (1);
else return (2 * fact(1));
long int fact (int n)
{
if (1 = = 0) return (1);
if (n = = 0) return (1);
else return (n * fact(n-1)); else return (1 * fact(0));
}
if (0 = = 0) return (1);
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2));

if (2 = = 0) return (1);
else return (2 * fact(1)); 1
long int fact (int n)
{
if (1 = = 0) return (1);
if (n = = 0) return (1);
else return (n * fact(n-1)); else return (1 * fact(0)); 1
}
if (0 = = 0) return (1);
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2)); 2

if (2 = = 0) return (1);
else return (2 * fact(1)); 1
long int fact (int n)
{ if (1 = = 0) return (1);
if (n = = 1) return (1);
else return (n * fact(n-1)); else return (1 * fact(0)); 1
} if (0 = = 0) return (1);
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3));

if (3 = = 0) return (1);
else return (3 * fact(2)); 2

if (2 = = 0) return (1);
else return (2 * fact(1)); 1
long int fact (int n)
{
if (1 = = 0) return (1);
if (n = = 0) return (1);
else return (n * fact(n-1)); else return (1 * fact(0)); 1
}
if (0 = = 0) return (1);
Factorial Execution
fact(4)

if (4 = = 0) return (1);
else return (4 * fact(3)); 6

if (3 = = 0) return (1);
else return (3 * fact(2)); 2

if (2 = = 0) return (1);
else return (2 * fact(1)); 1
long int fact (int n)
{
if (1 = = 0) return (1);
if (n = = 0) return (1);
else return (n * fact(n-1)); else return (1 * fact(0)); 1
}
if (0 = = 0) return (1);
Factorial Execution
fact(4) 24

if (4 = = 0) return (1);
else return (4 * fact(3)); 6

if (3 = = 0) return (1);
else return (3 * fact(2)); 2

if (2 = = 0) return (1);
else return (2 * fact(1)); 1
long int fact (int n)
{
if (1 = = 0) return (1);
if (n = = 0) return (1);
else return (n * fact(n-1)); else return (1 * fact(0)); 1
}
if (0 = = 0) return (1);
What happens for recursive calls?
• What we have seen ….
• Activation record gets pushed into the stack when a function call is made
• Activation record is popped off the stack when the function returns
• In recursion, a function calls itself
• Several function calls going on, with none of the function calls returning
back
• Activation records are pushed onto the stack continuously
• Large stack space required
• Activation records keep popping off when the termination condition of
recursion is reached

• We shall illustrate the process by an example of computing factorial


• Activation record looks like this:

Local
Variables
Return Value
Return Addr
Example:: main() calls fact(3)

int main()
{
int fact (n)
int n;
int n;
n = 3;
{
printf (“%d \n”, fact(n) );
if (n = = 0)
}
return (1);
else
return (n * fact(n-1));
}
TRACE OF THE STACK DURING EXECUTION

n=0
1
RA .. fact

main
n=1 n=1 n=1 fact
- - 1*1 = 1 returns
calls RA .. fact RA .. fact RA .. fact
fact to main
n=2 n=2 n=2 n=2 n=2
- - - - 2*1 = 2
RA .. fact RA .. fact RA .. fact RA .. fact RA .. fact
n=3 n=3 n=3 n=3 n=3 n=3 n=3
- - - - - - 3*2 = 6
RA .. main RA .. main RA .. main RA .. main RA .. main RA .. main RA .. main
Fibonacci Numbers
Fibonacci recurrence:
fib(n) = 0 if n = 0
=1 if n = 1
= fib(n – 2) + fib(n – 1)
otherwise;

int fib (int n) {


if (n == 0 ) // base case
return 0;
if (n == 1) // base case
return 1;
return fib(n-2) + fib(n-1) ; //Recursive call
}
int fib (int n) {
if (n == 0 )
return 0;
if (n == 1)
return 1;
return fib(n-2) + fib(n-1) ;
}
fib (5)

fib (3) fib (4)

fib (1) fib (2) fib (2) fib (3)

fib (0) fib (1) fib (0) fib (1) fib (1) fib (2)

fib (0) fib (1)


int fib (int n) {
if (n == 0 )
return 0;
if (n == 1)
return 1;
return fib(n-2) + fib(n-1) ;
fib (5) }

fib (3) fib (4)

fib (1) fib (2) fib (2) fib (3)


1

fib (0) fib (1) fib (0) fib (1) fib (1) fib (2)
1 0 1 1
0
fib (0) fib (1)

0 1
int fib (int n) {
if (n == 0 )
return 0;
if (n == 1)
return 1;
8 return fib(n-2) + fib(n-1) ;
fib (5) }

3 5
fib (3) fib (4)
1 2 2 3
fib (1) fib (2) fib (2) fib (3)
1 2
1 1 1 1 1
fib (0) fib (1) fib (0) fib (1) fib (1) fib (2)
1 0 1 1 1
0 1
fib (0) fib (1)

0 1
Function call sequence
Reversing number using recursion
#include<stdio.h>
int reverse(int num, int rev)​
{​
if(num==0)​
int reverse(int , int );
return rev;​
else​
return reverse(num/10, rev*10 + num%10);​
int main() }​
{
int number, result;
printf("Enter number: ");
scanf("%d", &number);
//2nd argument must be 0 while calling
result = reverse(number, 0);
printf("Reverse of %d is %d.", number,
result);
return 0;
}
Arrays -
Introduction

• An array is a collection of data items, all of the same type,


and are accessed using a common name.

• In other words, an array is a variable that can store


multiple data items of same data type.

• Usually, arrays are used to store and manipulate huge amounts


data items (it is not feasible to declare separate variables
when the number of data items to be stored is very large)

1
Array
s
• The locations of the array are accessed using the array name
combined with an index. For example, an array a[] that can
store six integers can be visualized as follows.

• The number of indices required to access an item in an array


is called dimension of an array. The above array is a one
dimensional array since we need only one index to access any
item.

• An array that requires two indices is called a matrix (2-D


array).
2
Declaring and Initializing 1-D
arrays
• Like variables, the arrays also must be declared before they
are used
• General syntax of 1-D array declaration statement
data-type array-name [size];
• Examples

int c[6];

char
ch[3];
• Following
examples
show the
initializatio
n of 1-D
arrays.
int
Points to
note

• An array must be declared with three attributes:


1.type of data
2. the number of data it can hold (size), and
3. the identifier (name).

• The array size must be a positive integer number or


an expression that evaluates to a positive integer

• The array index starts at 0 and ends at (size–1)

• C never checks whether the array index is valid—either at


compile time or when the program is running
Memory allocation of
arrays
• Memory allocation of an array is done in a contiguous manner.
That is, Starting from a given memory location, the successive
array elements are allocated space in consecutive memory
locations.

• a is the name of the array


• x is the starting address
• k is the number of bytes required for one element (for
example k is 4 for integer array)
• The element a[i] is allocated memory at x + i ∗ k
Memory allocation of
arrays

Assume that the memory allocation of the array starts at


location 100 (that is x =100) and the the size of the array is 7.
• If the array ar is a character array, then k = 1. The
memory allocation is shown below

• If the array ar is an integer array, then k = 4. The


memory allocation is shown below
Accessing array
elements

The following program shows how the array elements are


accessed in C.

int main(){
int ar[10];
/*A for loop to populate the array*/
for(int i=0;i<10;i++) scanf("%d", &ar[i]);

/*A for loop to print the array*/


for(int i=0;i<10;i++) printf("%d", ar[i]);

return 0;
}
Problem
1

Write a C program to find the average of the elements in an


integer array consisting of 10 elements
Problem 1 -
Solution
Write a C program to find the average of the elements in an
integer array consisting of 10 elements
int main(){
int ar[10], sum=0;

/*Populating the array */


for(int i=0;i<10;i++)
scanf("%d", &ar[i]);

/*Adding the array


elements*/
for(int i=0;i<10;i++)
sum+=ar[i];

printf("Average = %f",
sum/(float)10);
return 0;
Problem
2

Write a C program to find the largest element in an


array.
Solution

Write a C program to find the largest element in an


array.
1 int main()
2 {
3 int ar[10], max=0;
4 /*Populating the array */
5 for(int i=0;i<10;i++) scanf("%d", &ar[i]);
6

7 max=ar[0];
8 for(int i=1;i<10;i++)
9 if (ar[i]>max) max=ar[i];
10

11 printf("largest element = %d", max);


12 return 0;
13 }
Linear
Search
To search an element in a given unsorted
array.
1 int main()
2 {
3 int n;
4 scanf("%d",&n);
5 int ar[n], key, flag=0;
6 for(int i=0;i<n;i++) scanf("%d",
&ar[i]);
7 printf("Enter the search element");
8 scanf("%d",&key);
9

10 for(int i=1;i<n;i++)
11 if (ar[i]==key) {flag=1; break;}
12 if (flag)
13 printf("The element found");
14 else
15 printf("The element NOT found");
16 return 0;
17 }

You might also like