Recursividad
Recursividad
Recursividad
Algoritmos Recursivos
Luis Garrido
1
Matrushka
La Matrushka es una artesanía tradicional
rusa. Es una muñeca de madera que
contiene otra muñeca más pequeña dentro
de sí. Ésta muñeca, también contiene otra
muñeca dentro. Y así, una dentro de otra.
2
Recursividad: el concepto
6
Suma recursiva de los n primeros
números naturales
int SumaNat(int n)
{
int s;
if (n = = 1)
s = 1; // Caso Base
else
s = SumaNat(n-1) + n; // Caso general
return(s);
}
7
Funcionamiento de la recursividad
Nótese que en una función recursiva es
necesaria una condición para distinguir el caso
base del inductivo.
Para entender como funciona la recursividad
es necesario tener bien claro que en memoria
no existe una sola versión de la función
recursiva.
Cada vez que se invoque la función recursiva
se crea una nueva versión de la misma.
La estructura de todas la versiones es la
misma, pero no así los datos que contiene
cada una
8
Ejemplo: factorial
1! = 1
2! = 2 2*1
3! = 6 3*2*1
4! = 24 4*3*2*1
5! = 120 5*4*3*2*1
9
Ejemplo: factorial (iterativo -
repetetitivo)
regresa fact }
termina
10
Ejemplo: factorial (recursivo)
11
Ejemplo:
A continuación se puede ver la secuencia de
factoriales.
0! =1
1! = 1 =1*1 = 1 * 0!
2! = 2 =2*1 = 2 * 1!
3! = 6 =3*2 *1 = 3 * 2!
4! = 24 = 4 * 3 * 2 * 1 = 4 * 3!
5! = 120 = 5 * 4 * 3 * 2 * 1 = 5 * 4!
...
N! = = N * (N – 1)!
12
Solución
Aquí podemos ver la secuencia que toma el factorial
1 si N = 0 (base)
N! =
N * (N – 1) ! si N > 0 (recursión)
definición.
Solución Recursiva
Dado un entero no negativo x, regresar el factorial de x fact:
Entrada n entero no negativo,
Salida:entero. Es importante
determinar un caso
int fact (int n) base, es decir un
{ punto en el cual
if (n == 0) existe una
return 1; condición por la
else
cual no se requiera
return fact(n – 1) * n ;
volver a llamar a la
}
misma función.
14
¿Cómo funciona la recursividad?
Llamadas recursivas
15
Funcionamiento de la recursividad
Main
n=3 Devuelve 2*3 = 6 IDA VUELTA
Factorial(2)*3 Llamada n Valor
Factorial
n=2 1ª 3 6
Devuelve 1*2 = 2 2ª 2 2
Factorial Factorial(1)*2 3ª 1 1
4ª caso base 0 1
n=1
Devuelve 1*1 = 1
Factorial Factorial(0)*1
n=0
Devuelve 1
Factorial
16
¿Cómo funciona la
recursividad?
17
Factorial de un número
Caso base: fact(0) = 1
Caso general: fact(n) = fact(n-1)·n
Int fact(int n)
{
if n(= =0)
return(1);
else
return(fact(n-1)*n)
}
18
Funcionamiento de la recursividad
En el anterior ejemplo se ilustro cómo las llamadas
recursivas se van produciendo hasta alcanzar el caso base.
En ese punto se acaban las llamadas y empiezan las
devoluciones de valores hasta llegar al método main.
Tenemos un movimiento en 2 sentidos
1º Hacia delante hasta alcanzar el caso base.
2º Hacia atrás devolviendo los resultados de cada llamada a la
función.
Las llamadas realizadas implican una estructura pila.
En cada llamada se realiza una copia de la función recursiva
(cada llamada implica una nueva copia de las variables de la
función). Esto consume memoria.
19
Correctitud en la recursividad
¿Cómo podemos determinar si un Algoritmo Recursivo es o no
correcto?
Por simple observación es difícil.
Es posible alcanzar ese objetivo con la ayuda del principio de inducción.
Verificando 1º el caso base, comprobando si devuelve el resultado correcto para
el valor más pequeño.
Verificando si el algoritmo funciona correctamente para cualquier valor.
20
Recursividad vs. Iteración
Características comunes:
1. Ambas implican repetición
– La iteración usa explícitamente una estructura de repetición mientras que la
recursión logra la repetición mediante llamadas sucesivas a una función.
21
Recursividad vs. Iteración
22
Recursividad vs. Iteración
23
Recursividad vs. Iteración
Diferencias.
La recursividad presenta una desventaja frente a la iteración:
la invocación repetida de la función.Cada llamada hace que
se cree otra copia de la función esto puede consumir una
cantidad excesiva de memoria.
La iteración ocurre en la misma función, con lo que se omite
el gasto extra de llamadas a la función.
Toda tarea que pueda realizarse con recursividad puede
también realizarse con una solución iterativa.
Se elige la solución recursiva cuando este enfoque
refleja de forma más natural la solución del problema y
produce un programa más fácil de entender y depurar.
Existen problemas cuya solución iterativa no es viable
por lo tanto la recursión es una solución.
24
Simulación de la recursividad
def fib(n):
def fib(n): """ Precondición: n debe ser >= 0.
""" Precondición: n debe Devuelve: el número de fibonacci número n. """
ser >= 0. Devuelve: if n == 0 or n == 1: return n
el número de fibonacci ant2 = 0 ant1 = 1
número n. ""“ for i in xrange(2, n+1):
if n == 0 or n == 1: fibn = ant1 + ant2
return n ant2 = ant1
ant1 = fibn
return fib(n-1) + fib(n-2) return fibn
26
Pasos para convertir un ciclo
en un programa recursivo
1. Reemplazar el ciclo for por sus instrucciones
elementales
A. Asignar valor inicial a la variable controladora del ciclo
B. Escribir una instrucción if que compare el valor de la
variable controladora del ciclo con el valor final
C. Rotular el if escrito en B
D. Escribir las instrucciones propias del ciclo
E. Incremenetar la variable controladora del ciclo
F. Tansferir el control (GOTO) al label definido en C
G. Cerrar el if definido en B
27
Pasos para convertir un ciclo
en un programa recursivo
2. El subprograma recursivo lo conformarán todas las
instrucciones del ciclo y su parámetro es la variable
controladora del ciclo.
3. En el programa que lo llama se suprimen todas las
instrucciones del ciclo y se reemplaza el valor de
asignación del valor inicial de la variable controladora
del ciclo por un llamada recursiva. El valor del
parámetro en esta llamada es el valor inicial de la
variable controladora del ciclo.
4. En el subprograma se reemplazan las instrucciones de
incrementos de la variable controladora del ciclo y de
transferencia de control (goto) por una llamada
recursiva teniendo como parámetro la variable
controladora del ciclo modificada 28
Ejemplo para convertir un ciclo
en un programa recursivo
Sea el programa:
Read(n,x)
For (i = 1 to n ) haga
X=X+1
Endfor
Write x
I=1
Lb : If (i <= n ) Then
X=X+1
i=i+1
Goto Lb
Endif
Read(x,n)
SR(1)
Write(x)
Subprograma SR(i)
If i<=n then
x= x+1
SR(i+1)
Endif