2. Funciones Recursivas
Una función recursiva es una función que
se llama a sí misma.
El uso de funciones recursivas, llamado
recursión, puede brindar soluciones
refinadas a problemas complejos.
Mtl Lourdes Cahuich 2
3. Precaución con la recursividad
Un programador debe definir
cuidadosamente funciones recursivas,
para evitar crear una función que
repetidamente se llame a sí misma por
siempre.
Mtl Lourdes Cahuich 3
4. Cómo encontrar la recursividad
Una clave para crear y usar funciones
recursivas eficientes, es aprender a
pensar en un problema en términos de un
problema similar, pero más pequeño.
Mtl Lourdes Cahuich 4
6. Caso base
Eventualmente, un problema se hace lo
suficientemente pequeño que una función
puede solucionarlo sin usar recursión.
Esto es llamado caso base o quot;base casequot;.
Mtl Lourdes Cahuich 6
7. Ejemplo de recursión
El cálculo de factoriales es un ejemplo de
un problema que podemos resolver
usando recursión.
El factorial de un número es el producto
de todos los números enteros de ese
número hasta el uno.
Mtl Lourdes Cahuich 7
8. Ejemplo de recursión
Un signo de admiración denota el factorial
de un número.
Podemos expresar quot;cinco factorialquot; como
5!.
Mtl Lourdes Cahuich 8
10. Factorial
Podemos expresar los factoriales
recursivamente, es decir, en términos de
otros factoriales
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
0! = 1
Mtl Lourdes Cahuich 10
11. #include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int factorial(int n) {
if (n == 0) {
// base case
return 1;
}
else {
// recursive call
int value = factorial(n - 1);
return n * value;
}
}
int main(int argc, char* argv[]) {
cout << factorial(5) << endl;
return EXIT_SUCCESS;
}
Mtl Lourdes Cahuich 11
12. La Pila de Llamadas (Call Stack)
La pila de llamadas es un área en la
memoria del programa usada para
administrar la función ejecutada
actualmente y todas las llamadas
pendientes a la función.
La siguiente figura ofrece más detalles de
lo quiere decir una quot;llamada pendiente a la
funciónquot;.
Mtl Lourdes Cahuich 12
14. Pila de llamadas
En ella podemos ver que a pesar de que
la instancia de la función factorial con el
parámetro 5 fue la primera en comenzar la
ejecución, es la última en finalizarla.
Mtl Lourdes Cahuich 14
15. Pila de llamadas
El programa detiene la ejecución de
factorial(5)hasta que se complete la
llamada de la función a factorial(4).
De igual forma, el programa detiene la
ejecución de factorial(4) hasta que se
complete la llamada de la función a
factorial(3).
Mtl Lourdes Cahuich 15
16. Pila de llamadas
Esta serie de llamadas a las funciones
anidadas es administrada usando la pila
de llamadas
Mtl Lourdes Cahuich 16
19. Pila de llamadas
La pila de llamadas opera de la misma
forma con funciones recursivas que con
funciones regulares
Las funciones anidadas continúan
quot;desenredándosequot; de esta forma,
regresando valores a sus funciones de
llamada, hasta que la función se completa
y el programa termina.
Mtl Lourdes Cahuich 19
20. Depurador y recursividad
Los depuradores (debuggers) a menudo
tienen una característica que permite a los
programadores inspeccionar la pila de
llamadas de un programa.
Esta característica puede ser de gran
valor al tratar de depurar una función
recursiva.
Mtl Lourdes Cahuich 20
21. ¿Cómo eliminar una recursión?
La recursión tiene un precio: el sistema de
ejecución tiene que mantener una
complicada pila de llamadas, además de
tener que desarrollar las evaluaciones
usuales contenidas en la función.
A menudo podemos eliminar la recursión
en favor de la iteración, la cual no
demanda lo mismo en el sistema de
ejecución.
Mtl Lourdes Cahuich 21
22. Eliminando recursión
Por ejemplo, el siguiente bucle basado en
funciones factoriales garantiza una
ejecución más rápida y que consume
menos memoria (en la pila de llamadas)
que la versión recursiva presentada
anteriormente.
Mtl Lourdes Cahuich 22
23. int factorial(int n) {
int x = 1;
for (int i = 2; i <= n; ++i)
{
x *= i;
}
return x;
}
Mtl Lourdes Cahuich 23
24. Consideraciones finales recursión
Siempre es posible eliminar la recursión, y
vale la pena pensar en reemplazar la
recursión con bucles.
En algunos casos, de cualquier forma, la
recursión puede ser el mejor método.
Mtl Lourdes Cahuich 24
25. Consideraciones finales recursión
Versiones no-recursivas de ciertos
algoritmos pueden ser mucho más
complicadas de programar, que la
eficiencia obtenida no vale el esfuerzo
adicional
Mtl Lourdes Cahuich 25