Clase Teorica 03
Click here to load reader
-
Upload
sebas-olarte -
Category
Documents
-
view
215 -
download
0
description
Transcript of Clase Teorica 03
-
Estructuras de datos
Clase terica 3
Contenido
Recursividad
Uso dentro de estructuras de datos
Material elaborado por: Julin Moreno
Facultad de Minas, Departamento de Ciencias de la Computacin y la Decisin
-
Definicin: Un algoritmo es recursivo si se encuentra
definido en trminos de s mismo.
Recursividad / Recursin
Un ejemplo clsico de una funcin que puede definirse de
manera recursiva es el factorial de un nmero:
N! = N*(N-1)!, sabiendo que 1! = 1
Ejemplo: 4! = 4*(3!) = 4*3*(2!) = 4*3*2*(1!) = 4*3*2*1 = 24
-
Salida de recursin
Como se observ en el ejemplo anterior, en una funcin
recursiva debe existir por lo menos un caso donde la
respuesta se obtiene sin necesidad de hacer ms llamadas
recursivas, a este caso se le denomina salida de la
recursin (en el ejemplo anterior 1! = 1) y es necesario
para que la funcin no se quede en un ciclo infinito.
La recursin es muy til en ciertos problemas que por
naturaleza son recursivos. La desventaja sin embargo es
la gran cantidad de memoria que se ocupa debido al
llamado continuo de funciones que se van acumulando.
Cada llamado recursivo implica una copia en memoria de
la funcin, junto con sus argumentos y variables internas.
-
Ejemploimport java.util.*;
public class Main {
public static void main(String[] args) {
int x;
Scanner entrada = new Scanner(System.in);
x = entrada.nextInt();
System.out.println(factorial(x));
}
static long factorial(int N) {
if (N == 1)
return 1;
else
return (N * factorial(N-1));
}
}
factorial(4), N=4
factorial(3), N=3
Llama aDevuelve 3*2=6
factorial(2), N=2
Llama aDevuelve 2*1 = 2
factorial(1), N=1
Llama aDevuelve 1
Devuelve 4*6=24
-
Llamados mltiples
Hacer el rastreo a una funcin recursiva cuando solo se
hace un llamado por vez es relativamente simple (como en
el ejemplo anterior). Sin embargo, cuando hay ms de un
llamado es ms fcil de entender, no como una pila, si no
como un rbol de recursiones.
Miremos otro ejemplo clsico de una funcin que puede
definirse de manera recursiva: la serie de Fibonacci
Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
Sabiendo que Fibonacci(1) = 0, Fibonacci(2) = 1
*Recordemos: 0 1 1 2 3 5 8 13 21 34
-
Ejemploimport java.util.*;
public class Main {
public static void main(String[] args) {
int x;
Scanner entrada = new Scanner(System.in);
x = entrada.nextInt();
System.out.println(fib(x));
}
static long fib(int N) {
if (N == 1)
return 0;
else if (N == 2)
return 1;
else
return fin(N-1) + fib(N-2);
}
}
-
Ejemplo//...
System.out.println(fib(x));
fib(5), N=5
fib(4), N=4
Llama aDevuelve 1+1=2
fib(2), N=2
Llama aDevuelve 1+0=1
Devuelve 1
Devuelve 2+1=3
Suponiendo x=5
fib(3), N=3
fib(2), N=2 fib(1), N=1
Llama a
fib(3), N=3
fib(2), N=2 fib(1), N=1
Llama a Devuelve 0
Devuelve 1Devuelve 0
Devuelve 1+0=1
Devuelve 1
-
Llamados mltiples
Habiendo entendido como se hacen llamados mltiples dentro
de un proceso recursivo, hagamos una prueba de escritorio al
siguiente cdigo:
import java.util.*;
public class Main {
public static void main(String[] args) {
int x=6;
System.out.println(julianacci(x));
}
static long julianacci(int N) {
if (N
-
Recursividad y estructuras de datos
Hay estructuras de datos que por su naturaleza pueden hacer
uso de la recursividad para llevar a cabo sus operaciones (un
ejemplo de ello son las bsquedas en rboles y montculos
binarios).
Esto no quiere decir que siempre que trabajemos con
estructuras de datos necesitemos de recursividad ni que cada
que trabajemos con recursividad es porque estamos usando
estructuras de datos.
De hecho, como todo en este curso Cundo necesitamos
recursividad? Respuesta: Cuando el problema as lo requiera
Sin embargo, y considerando que los llamados recursivos
consumen memoria dado que hacen una copia de las variables
en cada llamado, la regla de oro ser: Solo usar un algoritmo
recursivo cuando no sea posible usar uno iterativo
-
Recursividad y estructuras de datos
Un ejemplo claro del uso de recursividad en conjunto con una
estructura de datos es el algoritmo mergeSort para ordenar un
arreglo.
A grueso modo, el mergeSort hace lo siguiente:
Si la longitud del arreglo (cantidad de elementos que
contiene) es 0 1, entonces ya est ordenado. En otro caso:
Separar el arreglo en dos sub-arreglos de aproximadamente
la mitad del tamao.
Ordenar cada sub-arreglo recursivamente.
Mezclar los dos sub-arreglos ya ordenados en un solo
arreglo ordenado y retornarlo.