230 likes | 241 Views
Explore the concept of recursive functions through the example of factorial computations. Learn how recursion is implemented and how it can be converted into a FORTRAN function.
E N D
Recursive functions • A recursive function is one which ‘calls itself’ • This is often the best solution for particular algorithms because it directly implements the mathematical definition of the solution. • Factorial is a good example
Iterative Factorial Function FUNCTION factorial(n) INTEGER :: factorial, i INTEGER INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDO END FUNCTION factorial
Factorial Program • The process of computing a factorial in the iterative program is straightforward • 5! = 1*2*3*4*5 • This looks like this when traced:
Trace of iterative factorial 1 FUNCTION factorial(n) INTEGER :: factorial, i INTEGER INTENT(IN) :: n 2 factorial = 1 3 DO i = 1, n 3.1 factorial = factorial * i ENDDO 4 END FUNCTION factorial n i factorial 1 5 ? ? 2 1 3 1 3.1 1 3 2 3.1 2 3 3 3.1 6 3 4 3.1 24 3 5 3.1 120 4. Returns 120
Recursive definition • The recursive definition of factorial is: 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1 * 0! 0! = 1
In other words... • To compute 5! You must first compute 4! • To compute 4! You must first compute 3! • To compute 3! You must first compute 2! • To compute 2! You must first compute 1! • To compute 1! You must first compute 0! • 0! Is 1
Recursive definition • For all positive integers n, • if n = 0: 0! = 1 • if n > 0: n! = n * (n-1)! • This can easily be turned into a recursive FORTRAN function.
From algorithm to code RECURSIVE FUNCTION factorial(n) RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 1 Declare variables 2. Compute factorial of n 2.1 IF n is 0 THEN 2.1.1 n! = 1 2.2 ELSE 2.2.1 n! = n * (n-1)! 3 End
How recursion works RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial nfact = n * factorial(n-1) 5 * factorial(4)
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) Recursive call to factorial nfact = n * factorial(n-1) 4 * factorial(3)
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) Recursive call to factorial nfact = n * factorial(n-1) 4 * factorial(3) Recursive call nfact = n * factorial(n-1) 3 * factorial(2)
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) Recursive call to factorial nfact = n * factorial(n-1) 4 * factorial(3) Recursive call nfact = n * factorial(n-1) 3 * factorial(2) Recursive call to factorial nfact = n * factorial(n-1) 2 * factorial(1)
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) Recursive call to factorial nfact = n * factorial(n-1) 4 * factorial(3) Recursive call nfact = n * factorial(n-1) 3 * factorial(2) Recursive call to factorial nfact = n * factorial(n-1) 2 * factorial(1) Recursive call to factorial nfact = n * factorial(n-1) 1 * factorial(0)
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) Recursive call to factorial nfact = n * factorial(n-1) 4 * factorial(3) Recursive call nfact = n * factorial(n-1) 3 * factorial(2) Recursive call to factorial nfact = n * factorial(n-1) 2 * factorial(1) Recursive call to factorial nfact = n * factorial(n-1) 1 * factorial(0) Recursive call to factorial nfact = 1
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) nfact = n * factorial(n-1) 4 * factorial(3) nfact = n * factorial(n-1) 3 * factorial(2) nfact = n * factorial(n-1) 2 * factorial(1) nfact = n * factorial(n-1) 1 * 1 Return to previous call nfact = 1
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) nfact = n * factorial(n-1) 4 * factorial(3) nfact = n * factorial(n-1) 3 * factorial(2) nfact = n * factorial(n-1) 2 * 1 Return to previous call nfact = n * factorial(n-1) nfact = 1
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) nfact = n * factorial(n-1) 4 * factorial(3) nfact = n * factorial(n-1) 3 * 2 Return to previous call nfact = n * factorial(n-1) nfact = 2
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * factorial(4) nfact = n * factorial(n-1) 4 * 6 Return to previous nfact = n * factorial(n-1) nfact = 6
How recursion works nfact = n * factorial(n-1) RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial 5 * 24 Return to previous call nfact = n * factorial(n-1) nfact = 24
How recursion works nfact = n * factorial(n-1) Return to main program RECURSIVE FUNCTION factorial(n) & RESULT (nfact) INTEGER :: nfact INTEGER INTENT(IN) :: n ! Compute factorial of n IF (n == 0) THEN nfact = 1 ELSE nfact = n * factorial(n-1) ENDIF END FUNCTION factorial nfact = 120
Definition: Recursion - The process of a function calling itself. Key considerations: A clearly defined stopping state must exist. If the recursive step works for 1 case, it must work for all cases (by induction) Any recursive subprogram can be rewritten using iteration and a stack.
The Costs of Recursion • There are two main costs • Space: maximum size of the stack • Time: number of recursive calls made • For factorial • The maximum size of the stack is O(n) • The maximum number of recursive calls made is also O(n)