Recursion. Functions – reminder A function can call other functions. Return causes the execution...

Post on 12-Jan-2016

229 views 0 download

transcript

Recursion

Functions – reminder

A function can call other functions. Return causes the execution of the function to

terminate and returns a value to the calling function.

The type of the value returned must be the same as the return-type defined for the function.

return-type name(argType1 arg1, argType2 arg2, …) {function body;return value;

}

A recursive definition

C functions can also call themselves! However, usually not with the same

parameters (why?) Some functions can be defined using

smaller occurrences of themselves.Such a definition is called a “recursive

definition” of a function.

Recursive calling

Example:void func(int n){

putchar(`*`);func(n);

}Infinite series of *What is the problem ?Look for other problem …

Factorial

By definition : n! = 1*2*3*… *(n-1)*n

Thus, we can also define factorial the following way: 0! = 1 n! = n*(n-1)! for n>0

(n-1)!

*n

Example - factorial

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);

}

int factorial(int n){ int fact = 1; while (n >= 1) {

fact *=n; n--;

} return fact;}

Conclusions for Recursive calling

Every recursive function has a “boundary condition”. The function stops calling itself when it is satisfied.

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…4*…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…3*…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…2*…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…

FactRec(1)n

1

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…

FactRec(1)n

1

Returns…

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…

FactRec(1)n

1

Returns…1

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…

FactRec(2)n

2

Returns…2*1

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…

FactRec(3)n

3

Returns…3*2

Recursive factorial – step by step

int factRec(int n){ if (n==0 || n==1) return 1;

return n*factRec(n-1);}

FactRec(4)n

4

Returns…4*6

1הדפסת מספרים- דוגמא

#include <stdio.h>void print1(int n){

if (n>=0){printf("%d

",n);print1(n-1);

{{void main(){

int i = 3;print1(i);putchar('\n');

{

3 2 1 0

2הדפסת מספרים- דוגמא

#include <stdio.h>void print2(int n){

if (n>=0){print2(n-1);printf("%d

",n);{

{void main(){

int i = 3;print2(i);putchar('\n');

{

0 1 2 3

3הדפסת מספרים- דוגמא

#include <stdio.h>void print3(int n){

if (n>=0){printf("%d ",n);print3(n-1);printf("%d ",n);

{{void main(){

int i = 3;print3(i);putchar('\n');

{

3 2 1 0 0 1 2 3

4הדפסת מספרים- דוגמא

#include <stdio.h>void print4(int n){

if (n>=0){print4(n-1);printf("%d ",n);print4(n-1);

{{void main(){

int i = 3;print4(i);putchar('\n');

{

0 1 0 2 0 1 0 3 0 1 0 2 0 1 0

Another example - power

Xy = x*x*…*x

Recursive definitions (assume non-negative y):

Base: x0=11. Xy = X*(Xy-1)

2. Xy = (Xy/2)2 (for even y’s only)

y times

Fibonacci Series

Fibonacci definition: n0 = 0

n1 = 1

nn = nn-1 + nn-2

0 1 1 2 3 5 8 13 21 34 55 …

Fibonacci Iterative

void fibonacci(int n) { int Fn, Fn1, Fn2, ind;  Fn2 = 0 ;

Fn1 = 1 ; Fn = 0 ;

if ( n == 1 )Fn = 1 ;

for (ind=2 ; ind <= n ; ind++){ Fn = Fn1 + Fn2; Fn2 = Fn1;

Fn1 = Fn;}

printf("F(%d) = %d \n", n, Fn);} 

Fibonacci Recursive

fibonacci(1)

fibonacci(5)

fibonacci(4) fibonacci(3)

fibonacci(3) fibonacci(2) fibonacci(2)

fibonacci(1)

fibonacci(2) fibonacci(1) fibonacci(1)

fibonacci(0)

fibonacci(0) fibonacci(1) fibonacci(0)

int fibonacci(int n) { if (n==0)

return 0; if (n==1)

return 1; return fibonacci(n-1) + fibonacci(n-2);}

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

2*…

y

5

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

y

4

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

y

4

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

y

4

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

y

2

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

y

2

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

y

2

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

2*…

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

2*…

y

1

rec_pow(2, 0)x

2

Returns…

y

0

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

2*…

y

1

rec_pow(2, 0)x

2

Returns…

y

0

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

2*…

y

1

rec_pow(2, 0)x

2

Returns…

1

y

0

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(…)

y

2

rec_pow(2, 1)x

2

Returns…

2*1

y

1

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(…)

y

4

rec_pow(2, 2)x

2

Returns…

square(2)

y

2

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

y

5

rec_pow(2, 4)x

2

Returns…

square(4)

y

4

rec_pow – step by step

int rec_pow(int x, int y){if (y == 0)

return 1;if (y%2 == 0)

return square(rec_pow(x,y/2));else

return x*rec_pow(x,y-1);}

rec_pow(2, 5)x

2

Returns…

2*16

y

5

Exercise

Write a program that receives two non-negative integers and computes their product recursively.

Not * multiple operator !!

Hint: Notice that the product a*b is actually a+a+…+a (b times).

Solution

int recMult( int x, int y ) {if( x == 0)

return 0;return y + recMult( x-1,y);

{

Exercise

Given the following iterative version of sum-of-digits calculation

Find the recursive definition of this function

(don’t forget the base case!)

int sum_digits(int n){int sum = 0;while (n > 0) {

sum += n%10;n = n/10;}return sum;

}

Solution

int sumOfDigits( int x ) {if( x < 0)

x *= -1;if( x == 0 )

return 0;else

return x % 10 + sumOfDigits( x / 10 );

}

More uses

Recursion is a general approach to programming functions.

Its uses are not confined to calculating mathematical expressions!

For example : write a function that finds the max member in an array of integer.

Solution

int rec_max(int arr[ ], int size){int rest;if (size == 1)

return arr[0];else {

rest = rec_max(arr+1, size-1); if (arr[0] > rest) return arr[0];else return rest;

}}

חיפוש בינארי

int BinarySearch(int arr[],int x, int left, int right) { int middle;if(left>right) return -1; else { middle=(left+right)/2); if(arr[middle]==x)

return middle; else if(x < arr[middle])

return BinarySearch(arr,x,left,middle-1); else return

BinarySearch(arr,x,middle+1,right); }

}

Towers of Hanoi

The Towers of Hanoi problem consists of three rods, and a number of disks of different sizes which can slide onto any rod. The puzzle starts with the disks in a neat stack in ascending order of size on one rod, the smallest at the top, thus making a conical shape.

The objective of the puzzle is to move the entire stack to another rod, obeying the following rules: Only one disk may be moved at a time. Each move consists of taking the upper disk from

one of the rods and sliding it onto another rod, on top of the other disks that may already be present on that rod.

No disk may be placed on top of a smaller disk.

Towers of Hanoi

Recursive Solution

To move n disks from peg A to peg C: move n−1 disks from A to B. This leaves disk

#n alone on peg A move disk #n from A to C move n−1 disks from B to C so they sit on

disk #n

Recursive Solution - Function

void hanoi(int x, char from, char to, char aux){ if(x==1){

printf("Move Disk From %c to %c\n", from, to);

}else {

hanoi(x-1,from,aux,to);printf("Move Disk From %c to %c\n",

from, to);hanoi(x-1,aux,to,from);

}}

Scope of variables - reminder

A variable declared within a function is unrelated to variables declared elsewhere.

A function cannot access variables that are declared in other functions.