Recursividad Franco Guidi Polanco Escuela de Ingeniería Industrial Pontificia Universidad Católica de Valparaíso, Chile fguidi@ucv.cl
Recursividad v Es la técnica de definir un proceso en términos de si mismo. v Por ejemplo, la definición de una Lista : Una LISTA es: número número coma LISTA v La definición anterior caracteriza como Lista cada una de las siguientes secuencias de números: 23, 12, 23, 4 7 1, 6 2
Recursividad v Otro ejemplo de recursividad: el factorial de un número. factorial( x ) = x * factorial( x-1 ) si x > 0 1 si x = 0 3
Ejemplo de función recursiva v Implementación de la función Factorial: public class Utiles { public static int factorial(int n){ if( n > 0 ) return n*factorial( n-1 ); else return 1; public class Ejemplo { public static void main(string[] arg){ System.out.println(Utiles.factorial( 4 )); 4
Ejemplo de función recursiva (cont.) public static int factorial(int n){ if( n > 0 ) return n*factorial(n-1); else return 1; Stack de invocaciones del método factorial n=0 return 1 n=1 return 1*factorial(0) n=2 return 2*factorial(1) n=3 return 3*factorial(2) n=4 return 4*factorial(3) r=utiles.factorial(4); 5
Ejemplo de función recursiva (cont.) public static int factorial(int n){ if( n > 0 ) return n*factorial(n-1); else return 1; factorial=1 factorial=1 factorial=2 factorial=6 n=0 return 1 Stack de invocaciones del método factorial n=1 return 1*factorial(0) n=2 return 2*factorial(1) n=3 return 3*factorial(2) n=4 return 4*factorial(3) factorial=24 r=utiles.factorial(4); 6
Recursividad y condición de término v Debe existir una condición de término o caso base, que establezca cuando el método debe dejar de invocarse recursivamente. v Debe existir una convergencia a la condición de término en las sucesivas invocaciones al método recursivo. public static int factorial(int n){ if( n > 0 ) return n*factorial( n-1 ); else return 1; Condición de término: Si n==0 se retorna 1. Convergencia hacia condición de término: n se avecina a 0 en cada invocación. 7
Tipos de recursividad v Recursividad directa: cuando un método P contiene dentro de si un llamado a si mismo. v Recursividad indirecta: cuando un método P contiene dentro de si un llamado a otro método Q que contiene llamados (directos o indirectos) a P. 8
Recursividad y variables locales v Si un método recursivo utiliza variables locales, estas serán creadas para cada invocación del método. Las variables locales (y sus valores) serán visibles sólo en la correspondiente invocación (cada invocación del procedimiento tiene su propia área de datos). v Cada invocación a un procedimiento requiere de cierto espacio de memoria, el que sólo es liberado al terminar la ejecución de éste. El espacio de memoria disponible es limitado. v Los métodos recursivos son normalmente más lentos y consumen más memoria que sus equivalentes no recursivos. 9
Ejemplo 1 v Plantear una función recursiva para calcular la suma de los N primeros enteros positivos. v Análisis: Suma( N ) = 1 si N = 1 Caso base N + Suma( N-1 ) si N > 1 public static int suma(int n){ if( n == 1 ) return 1; else return n + suma( n-1 ); Supuesto en esta implementación: el valor de n ingresado inicialmente es mayor que 0. 10
Ejemplo 1 (cont.) Suma(3) Suma(2) Suma(1) Suma(4) 4+6=10 Suma(3) 3+3=3 Suma(2) 2+1=3 Suma(1) 6 3 1 11
Ejemplo 2 v Calcular el n-ésimo numero de Fibonacci. v Análisis: Fib(N) = v Ejemplo: 0 si N = 0 1 si N = 1 Fib(N-1) + Fib(N-2) si N > 1 Casos base Fib( 0 ) = 0 Fib( 1 ) = 1 Fib( 2 ) = Fib(1) + Fib(0) = 1 + 0 = 1 Fib( 3 ) = Fib(2) + Fib(1) = 1 + 1 = 2 Fib( 4) = Fib(3) + Fib(2) = 2 + 1 = 3 12
Ejemplo 2 (cont.) v Implementación: public static int fibonacci(int n){ if( n <= 1 ) return n; else return fibonacci( n-1 ) + fibonacci( n-2 ); 13
Ejemplo 2 (cont.) Fib(1) Fib(1) Fib(2) Fib(2) 1+0=1 1 Fib(0) Fib(3) Fib(3) 1+1=2 1 Fib(1) 0 Fib(0) Fib(4) 2+1=3 2 1 1 Fib(1) Fib(1) Fib(1) Fib(2) 1+0=1 1 Fib(0) 0 Fib(0) 14
Una ayuda para saber si entendí la recursividad Test de aprendizaje de recursividad: Si no está seguro de entender la recursividad lea el Test de aprendizaje de recursividad en caso contrario deténgase, Ud. ya entendió. v Nota: este test sólo es capaz de concluir (en un tiempo suficientemente largo) que Ud. está seguro de haber entendido la recursividad (no es capaz de concluir lo contrario). 15