11 recursion

25
3.1 3.1 Recursión Recursión Apoyo SSD5 Apoyo SSD5

Upload: uvm

Post on 13-Jun-2015

2.164 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 11 Recursion

3.1 3.1 RecursiónRecursión

Apoyo SSD5Apoyo SSD5

Page 2: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 22

Funciones RecursivasFunciones Recursivas

�� Una Una función recursivafunción recursiva es una función que es una función que se llama a sí misma. se llama a sí misma.

�� El uso de funciones recursivas, llamado El uso de funciones recursivas, llamado recursiónrecursión, puede brindar soluciones , puede brindar soluciones refinadas a problemas complejos. refinadas a problemas complejos.

Page 3: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 33

Precaución con la recursividadPrecaución con la recursividad

�� Un programador debe definir Un programador debe definir cuidadosamente funciones recursivas, cuidadosamente funciones recursivas, para evitar crear una función que para evitar crear una función que repetidamente se llame a sí misma por repetidamente se llame a sí misma por siempre. siempre.

Page 4: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 44

Cómo encontrar la recursividadCómo encontrar la recursividad

�� Una clave para crear y usar funciones Una clave para crear y usar funciones recursivas eficientes, es aprender a recursivas eficientes, es aprender a pensar en un problema en términos de un pensar en un problema en términos de un problema similar, pero más pequeño. problema similar, pero más pequeño.

Page 5: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 55

Page 6: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 66

Caso baseCaso base

�� Eventualmente, un problema se hace lo Eventualmente, un problema se hace lo suficientemente pequeño que una función suficientemente pequeño que una función puede solucionarlo sin usar recursión. puede solucionarlo sin usar recursión.

�� Esto es llamado Esto es llamado caso basecaso base o o "base case""base case"..

Page 7: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 77

Ejemplo de Ejemplo de recursiónrecursión

�� El cálculo de factoriales es un ejemplo de El cálculo de factoriales es un ejemplo de un problema que podemos resolver un problema que podemos resolver usando recursión. usando recursión.

�� El factorial de un número es el producto El factorial de un número es el producto de todos los números enteros de ese de todos los números enteros de ese número hasta el uno. número hasta el uno.

Page 8: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 88

Ejemplo de Ejemplo de recursiónrecursión

�� Un signo de admiración denota el factorial Un signo de admiración denota el factorial de un número. de un número.

�� Podemos expresar "cinco factorial" como Podemos expresar "cinco factorial" como 5!. 5!.

Page 9: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 99

FactorialFactorial

5! = 5 * 4 * 3 * 2 * 1 = 1205! = 5 * 4 * 3 * 2 * 1 = 120

4! = 4 * 3 * 2 * 1 = 244! = 4 * 3 * 2 * 1 = 24

3! = 3 * 2 * 1 = 63! = 3 * 2 * 1 = 6

2! = 2 * 1 = 22! = 2 * 1 = 2

1! = 11! = 1

0! = 1 0! = 1

Page 10: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1010

FactorialFactorial

�� Podemos expresar los factoriales Podemos expresar los factoriales recursivamente, es decir, en términos de recursivamente, es decir, en términos de otros factoriales otros factoriales 5! = 5 * 4!5! = 5 * 4!

4! = 4 * 3! 4! = 4 * 3!

3! = 3 * 2! 3! = 3 * 2!

2! = 2 * 1!2! = 2 * 1!

1! = 1 * 0!1! = 1 * 0!

0! = 1 0! = 1

Page 11: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1111

#include <#include <iostreamiostream>>#include <#include <cstdlibcstdlib>>#include <string>#include <string>using namespace std;using namespace std;intint factorial(intfactorial(int n) {n) {

if (n == 0) { if (n == 0) { // base case// base casereturn 1;return 1;

}}else {else {

// recursive call // recursive call intint value = value = factorial(nfactorial(n -- 1);1);return n * value;return n * value;

}}}}intint main(intmain(int argcargc, char* , char* argvargv[]) {[]) {

coutcout << factorial(5) << << factorial(5) << endlendl;;return EXIT_SUCCESS;return EXIT_SUCCESS;

} }

Page 12: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1212

La Pila de Llamadas (La Pila de Llamadas (CallCall StackStack))

�� La La pila de llamadaspila de llamadas es un área en la es un área en la memoria del programa usada para memoria del programa usada para administrar la función ejecutada administrar la función ejecutada actualmente y todas las llamadas actualmente y todas las llamadas pendientes a la función. pendientes a la función.

�� La siguiente figura ofrece más detalles de La siguiente figura ofrece más detalles de lo quiere decir una "llamada pendiente a la lo quiere decir una "llamada pendiente a la función". función".

Page 13: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1313

Page 14: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1414

Pila de llamadasPila de llamadas

�� En ella En ella podemos ver que a pesar de que podemos ver que a pesar de que la instancia de la función factorial con el la instancia de la función factorial con el parámetro 5 fue la primera en comenzar la parámetro 5 fue la primera en comenzar la ejecución, es la última en finalizarla. ejecución, es la última en finalizarla.

Page 15: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1515

Pila de llamadasPila de llamadas

�� El programa detiene la ejecución de El programa detiene la ejecución de factorial(5)hasta que se complete la factorial(5)hasta que se complete la llamada de la función a factorial(4).llamada de la función a factorial(4).

�� De igual forma, el programa detiene la De igual forma, el programa detiene la ejecución de factorial(4) hasta que se ejecución de factorial(4) hasta que se complete la llamada de la función a complete la llamada de la función a factorial(3). factorial(3).

Page 16: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1616

Pila de llamadasPila de llamadas

�� Esta serie de llamadas a las funciones Esta serie de llamadas a las funciones anidadas es administrada usando la pila anidadas es administrada usando la pila de llamadas de llamadas

Page 17: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1717

#include <#include <iostreamiostream>>#include <#include <cstdlibcstdlib>>using namespace std;using namespace std;void method3(void) {void method3(void) {

coutcout << "Method 3" << << "Method 3" << endlendl;;}}void method2(void) {void method2(void) {

method3();method3();}}void method1(void) {void method1(void) {

method2();method2();}}intint main(intmain(int argcargc, char* , char* argvargv[]) {[]) {

method1();method1();returnreturn EXIT_SUCCESSEXIT_SUCCESS;;

} }

Page 18: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1818

Page 19: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 1919

Pila de llamadasPila de llamadas

�� La pila de llamadas opera de la misma La pila de llamadas opera de la misma forma con funciones recursivas que con forma con funciones recursivas que con funciones regulares funciones regulares

�� Las funciones anidadas continúan Las funciones anidadas continúan "desenredándose" de esta forma, "desenredándose" de esta forma, regresando valores a sus funciones de regresando valores a sus funciones de llamada, hasta que la función se completa llamada, hasta que la función se completa y el programa termina. y el programa termina.

Page 20: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2020

Depurador y recursividadDepurador y recursividad

�� Los depuradores (Los depuradores (debuggersdebuggers) a menudo ) a menudo tienen una característica que permite a los tienen una característica que permite a los programadores inspeccionar la pila de programadores inspeccionar la pila de llamadas de un programa.llamadas de un programa.

�� Esta característica puede ser de gran Esta característica puede ser de gran valor al tratar de depurar una función valor al tratar de depurar una función recursiva. recursiva.

Page 21: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2121

¿Cómo eliminar una ¿Cómo eliminar una recursiónrecursión??

�� La recursión tiene un precio: el sistema de La recursión tiene un precio: el sistema de ejecución tiene que mantener una ejecución tiene que mantener una complicada pila de llamadas, además de complicada pila de llamadas, además de tener que desarrollar las evaluaciones tener que desarrollar las evaluaciones usuales contenidas en la función.usuales contenidas en la función.

�� A menudo podemos eliminar la recursión A menudo podemos eliminar la recursión en favor de la iteración, la cual no en favor de la iteración, la cual no demanda lo mismo en el sistema de demanda lo mismo en el sistema de ejecución. ejecución.

Page 22: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2222

Eliminando Eliminando recursiónrecursión

�� Por ejemplo, el siguiente bucle basado en Por ejemplo, el siguiente bucle basado en funciones factoriales garantiza una funciones factoriales garantiza una ejecución más rápida y que consume ejecución más rápida y que consume menos memoria (en la pila de llamadas) menos memoria (en la pila de llamadas) que la versión recursiva presentada que la versión recursiva presentada anteriormente.anteriormente.

Page 23: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2323

intint factorial(intfactorial(int n) {n) {

intint x = 1;x = 1;

for (for (intint i = 2; i <= n; ++i) i = 2; i <= n; ++i) {{

x *= i;x *= i;

}}

returnreturn x;x;

} }

Page 24: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2424

Consideraciones finales Consideraciones finales recursiónrecursión

�� Siempre es posible eliminar la recursión, y Siempre es posible eliminar la recursión, y vale la pena pensar en reemplazar la vale la pena pensar en reemplazar la recursión con bucles.recursión con bucles.

�� En algunos casos, de cualquier forma, la En algunos casos, de cualquier forma, la recursión puede ser el mejor método. recursión puede ser el mejor método.

Page 25: 11 Recursion

Mtl Lourdes CahuichMtl Lourdes Cahuich 2525

Consideraciones finales Consideraciones finales recursiónrecursión

�� Versiones noVersiones no--recursivas de ciertos recursivas de ciertos algoritmos pueden ser mucho más algoritmos pueden ser mucho más complicadas de programar, que la complicadas de programar, que la eficiencia obtenida no vale el esfuerzo eficiencia obtenida no vale el esfuerzo adicional adicional