recursión - dc.uba.ar · triángulo de sierpinsky •construcción: 1. comenzamos con un...

Post on 26-Apr-2018

217 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Recursión

Introducción a la Computación

Clase 15

Patricia Borensztejn

El concepto de la recursión

• Recursión, recurrencia o recursividad es la forma en la cual se especifica un proceso basado en su propia definición.

Mas imágenes recursivas

• Triángulo de Sierpinsky (1915)

Triángulo de Sierpinsky

• Construcción:

1. Comenzamos con un triángulo.

2. Lo reducimos a la mitad de la altura y la mitad del lado y lo triplicamos, haciendo que cada uno toque a los otros dos en un extremo

3. Volvemos al paso 2 por cada triángulo generado.

Recursión

• Definición de la sintaxis de un lenguaje de programación (LISP):

– expresión ::= átomo | lista

– átomo ::= número | símbolo

– número ::= [+-]?['0'-'9']+

– símbolo ::= ['A'-'Z'<nowiki>'</nowiki>a'-'z'].*

– lista ::= '(' expresión* ')'

Recursión: factorial

• Definición de una función matemática de forma recursiva:

Recursión en los lenguajes de programación

• Una función que se llama a si misma directa o indirectamente, es una función recursiva.

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3 factorial(2)

*

2 factorial(1)

Camino de Ida: se contruye por cada activación de la función su bloque de activación en la pila

Camino de Ida

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3 factorial(2)

*

2

Camino de vuelta

factorial(1) devuelve 1 Y se libera su bloque de activación

1

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 factorial(3)

*

3

Camino de vuelta

factorial(2) devuelve 2 Y se libera su bloque de activación

2

Factorial recursivo

factorial(5)

*

5 factorial(4)

*

4 6

Camino de vuelta

factorial(3) devuelve 6 Y se libera su bloque de activación

Factorial recursivo

factorial(5)

*

5 24

Camino de vuelta

factorial(4) devuelve 24 Y se libera su bloque de activación

Factorial recursivo

factorial(5) devuelve 120 Y se libera su bloque de activación

Factorial recursivo, versión en C

• Mostramos también el estado de la pila con los bloques de activación …. en que momento? O sea, que estamos viendo en la pantalla?

Recursión indirecta y declaración anticipada en C

• El problema es que par llama a impar, con lo cual impar debe estar antes, pero impar llama a par: esto se llama recursión indirecta

• En el lenguaje C, debemos declarar las variables, los tipos y las funciones antes de usarlas.

• ¿Como haríamos en este caso?

Declaración anticipada • En realidad, C no necesita

conocer TODA la función antes de que sea usada, sino solamente su cabecera: nombre, tipo de retorno y parámetros.

• La solución es entonces incluir la cabecera antes de su uso.

• La declaración anticipada puede usarse cuando uno quiera, sin necesidad que se trata de funciones recursivas indirectas, pues a veces facilita la lectura de los programas

• Dibujar el estado de la pila para la llamada impar(7) cuando se llega al caso base.

Manos Dibujando Maurits Cornelius Escher (1948)

Recursión e Iteración

• La recursión es una herramienta poderosa pero ocupa muchos recursos en espacio y en tiempo.

• La recursión es una herramienta de repetición mucho mas poderosa que la iteración, debido a que la iteración funciona a nivel de bloque básico (lo que se repiten son un conjunto de sentencias acabadas con un GOTO), en cambio en la recursión se repite la función completa.

• Asi como es importante «salir del bucle», no quedarnos «colgados», en la recursión debemos garantizar el camino de regreso.

Recursión e Iteración

“Iterar es humano, ‘recursivar’ es divino” dijo

L. Peter Deutsch

Recursión e Iteración

“Iterar es humano, ‘recursivar’ es diabólico” digo

Yo!

De recursivo a iterativo

• Para toda función recursiva existe un algoritmo iterativo.

• No siempre es sencillo encontrarlo… aunque hay métodos que nos ayudan…

Recursivo es mas fácil de pensar

• Una ventaja de los recursivos es que es mas sencillo de pensar… (y mas bello a veces)

• Por ejemplo: pensamos en una función recursiva que calcule el número de bits necesario para representar un número entero. – Caso base: para representar el número 0 o el

número 1 necesitamos un bit

– Caso general: para representar el número n necesitamos un bit mas que para representar el número n/2, no? (la división es entera)

Recursivo: número de bits necesario para representar el número n

Fibonacci recursivo

• Un mal ejemplo:

Fibonacci recursivo

• En la versión recursiva, por cada llamada a función hay dos llamadas a la función, cada una de las cuales genera como mucho otras dos llamadas y así sucesivamente: es decir, el número de llamadas crece de forma exponencial con n, es decir, crece muy rápidamente. Es del orden 2n.

Fibonacci iterativo

• En la versión iterativa, el número de pasos es proporcional a n, es decir, crece linealmente con la entrada n. (se agrega una iteración mas)

• Por eso la versión iterativa es mejor que la recursiva, aunque no estamos diciendo que sea la mejor solución… podría haber alguna otra mejor.

Torres de Hanoi

• Reglas:

– Solo podemos mover el disco superior del montón.

– El disco superior debe moverse de una aguja a otra de tal manera que jamás quede debajo de él un disco de mayor tamaño.

Torres de Hanoi

• Para pasar el primer disco a la aguja final, las dos últimas situaciones deben ser las siguientes:

• Es decir, para resolver Hanoi(4, aguja inicial, aguja final), debemos: – resolver Hanoi(3, aguja

inicial, aguja libre) – Mover disco (aguja inicial,

aguja final) – Resolver Hanoi(3, aguja

libre, aguja final)

Hanoi

Hanoi

• El problema de Hanoi… es hacerlo iterativo. ¿Alguien se atreve?

Problemas Recursivos

Dibujando fractales, próximamente…

• Los fractales son objetos cuya estructura se repite a diferentes escalas.

• Se definen mediante simples algoritmos recursivos…

• Cuando sepamos dibujar, dibujaremos fractales usando recursión…

top related