* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Lecture 11
Functional decomposition wikipedia , lookup
Big O notation wikipedia , lookup
Mathematics of radio engineering wikipedia , lookup
Dirac delta function wikipedia , lookup
Principia Mathematica wikipedia , lookup
Series (mathematics) wikipedia , lookup
Elementary mathematics wikipedia , lookup
Function (mathematics) wikipedia , lookup
History of the function concept wikipedia , lookup
Computability theory wikipedia , lookup
ICS103 Programming in C Lecture 11: Recursive Functions 1 Outline • • • • • • • Recursive functions and Recursion Writing a recursive function Recursion vs Repetition Tracing Recursive Functions Examples Mutually recursive functions Common errors 2 What is a recursive function? • A recursive function is a function that calls itself either directly or indirectly • In C, any function can call itself Example: What is the output of the following program? #include <stdio.h> main() { printf(" Going around! "); main(); } 3 Why recursive functions? • Recursion is a powerful problem solving technique • Many mathematical functions can be defined recursively • Example: Factorial Function 5! = 5 * 4 * 3 * 2 * 1 or 5! = 5 * 4! 0! = 1 base case in general 1 n=0 n! = n (n-1)! n>0 recursive case • By re-appling the recursive case(s), solution will move closer and eventually reach the base case(s) 4 Writing a recursive function if this is a base case solve it else redefine the problem using recursion • Recursive functions generally involve an if statement • The if-branch is the base case, while the else-branch is the recursive case. • The recursive case provides the repetition needed for the solution and the base case provides the termination. • For the recursion to terminate, each recursive call must be moving closer to a base case. 5 Recursion vs Repetition Computing the factorial of a number n Recursive version int factorial (int n){ if (n == 0) return 1; else return n * factorial (n-1); } Iterative version int factorial (int n){ int i, product=1; for (i=n; i>1; --i) product=product * i; return product; } 6 Tracing Recursive Functions Executing recursive algorithms goes through two phases: Expansion in which each recursive step is applied until reaching a base step “Substitution” in which the solution is constructed backwards starting with the base step(s) factorial(4) = 4 * factorial (3) = 4 * (3 * factorial (2)) Expansion phase = 4 * (3 * (2 * factorial (1))) = 4 * (3 * (2 * (1 * factorial (0)))) = 4 * (3 * (2 * (1 * 1))) = 4 * (3 * (2 * 1)) = 4 * (3 * 2) =4*6 = 24 Substitution phase 7 Example 1: Multiplication Write a recursive function to compute m x n (where both m and n are integers) • The best way to go about this is to identify the base case and the recursive case. • base case: if n is 1, then m*n = m • recursive case: if n > 1, then m*n = m + m * (n-1). m, n=1 m*n m + m*(n-1), n>1 8 Example 1: Multiplication (cont.) #include <stdio.h> int multiply(int m, int n); int main(void) { int num1, num2; printf("Enter two integer numbers to multiply: "); scanf("%d%d", &num1, &num2); printf("%d x %d = %d\n", num1, num2, multiply(num1, num2)); system("pause"); return 0; } int multiply(int m, int n) { if (n == 1) return m; else return m + multiply(m, n } /* simple case */ - 1); /* recursive step */ 9 Example 1: Multiplication (cont.) multiply(5,4) Expansion phase = 5 + multiply(5, 3) = 5 + (5 + multiply(5, 2)) = 5 + (5 + (5 + multiply(5, 1))) = 5 + (5 + (5 + 5)) = 5 + (5 + 10) = 5 + 15 = 20 Substitution phase 10 Example 2: Power function • Suppose we wish to define our own power function that raises a double number to the power of a non-negative integer exponent. xn , n >= 0. • The base case is if n is 0. The answer is 1. • The recursive case is: xn = x * xn-1. 1, n = 0 xn x * x n-1, n>0 11 Example 2: Power function (cont.) #include <stdio.h> double pow(double x, int n); int main(void) { double x; int n; printf("Enter double x and integer n to find pow(x,n): "); scanf("%lf%d", &x, &n); printf("pow(%f, %d) = %f\n", x, n, pow(x, n)); system("pause"); return 0; } double pow(double x, int n) { if (n == 0) return 1; else return x * pow(x, n } /* simple case */ - 1); /* recursive step */ 12 Example 3: Fibonacci Function • Suppose we wish to define a function to compute the nth term of the Fibonacci sequence. • Fibonacci is a sequence of number that begins with the term 0 and 1 and has the property that each succeeding term is the sum of the two preceding terms: • Thus, the sequence is: 0, 1, 1,2,3,5,8,13,21,34 … • Mathematically, the sequence can be defined as: n, n = 0, 1 fib(n) fib(n-1) + fib(n-2) n>1 13 Example 3: Fibonacci Function (cont’d) #include <stdio.h> int fib(int n); int main(void) { int n; printf("Enter an integer n to find the nth fibonacci term: "); scanf("%d", &n); printf("fibonacci(%d) = %d\n", n, fib(n)); system("pause"); return 0; } int fib(int n) { if (n == 0 || n== 1) return n; else return fib(n-1) + fib(n-2); } /* simple case */ /* recursive step */ 14 Example 3: Fibonacci Function (cont’d) • Another way to trace a recursive function is by drawing its recursive tree • Example: The recursive tree for fib(6) is: 15 Example 4 Draw a recursive tree for the call display(3) and determine the program output #include <stdio.h> void display(int); int main(void){ display(3); system("pause"); return 0; } void display(int n){ if(n > 0){ printf("RIYADH\n"); display(n - 1); printf("DAMMAM\n"); } } • The blue numbers indicate the order in which the strings are printed. • Hence the output is: RIYADH RIYADH RIYADH DAMMAM DAMMAM DAMMAM 16 Example 5: Mutually recursive functions • Mutually recursive Trigonometric functions double sin(double x){ if(x < 0.0000001) return x - (x*x*x)/6; else{ double y = tan(x/3); return sin(x/3)*((3 - y*y)/(1 + y*y)); } } double tan(double x){ return sin(x)/cos(x); } double cos(double x){ double y = sin(x); return sqrt(1 - y*y); } 17 Example 6: Mutually recursive functions • Mutually recursive functions to check whether a positive integer is even or odd int isEven(int n) { if (n==0) return 1; else return(isOdd(n - 1)); } int isOdd(int n) { Exercise: return (! isEven(n)); 1. Draw the recursive tree for: } (a) isEven(2) (b) isEven(3) (c) isOdd(5) 2. Write a main method to test the above mutually recursive functions 18 Some Common Errors in Writing Recursive Functions 1. The function does not call itself directly or indirectly. 2. Non-terminating Recursive Functions (Infinite recursion): (a) No base case. int badFactorial(int x) { return x * badFactorial(x-1); } (b) The base case is never reached for some parameter values. int anotherBadFactorial(int x) { if(x == 0) return 1; else return x*(x-1)*anotherBadFactorial(x - 2); // When x is odd, we never reach the base case!! } 19 Some Common Errors in Writing Recursive Functions (cont’d) 3. Using a local variable (a variable declared within a function) wrongly to accumulate the result of a recursion int sumFirst_n_PositiveInts(int n) { int sum = 0; if(n == 1) return sum; else{ sum = sum + n; return sumFirst_n_PositiveInts(n – 1); } } In the above example, the local variable sum is reinitialized to zero in each recursive call (each call has its own sum). Hence, the returned value is 0. One correct solution is: int sumFirst_n_PositiveInts(int n) { if(n == 1) return n; else return n + sumFirst_n_PositiveInts(n – 1); } 20