Está en la página 1de 10

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

Recursividad / Recursin
Definicin: Un algoritmo es recursivo si se encuentra
definido en trminos de s mismo.

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.

Ejemplo
import 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));
}

Devuelve 4*6=24
factorial(4), N=4

static long factorial(int N) {


if (N == 1)
return 1;
else
return (N * factorial(N-1));
}

Devuelve 3*2=6

Llama a
factorial(3), N=3

Devuelve 2*1 = 2

Llama a
factorial(2), N=2

Devuelve 1

Llama a
factorial(1), N=1

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

Ejemplo
import 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));

Devuelve 2+1=3

Suponiendo x=5
fib(5), N=5
Devuelve 1+0=1

Devuelve 1+1=2

Llama a
fib(4), N=4

fib(3), N=3
Devuelve 0

Devuelve 1
Devuelve 1+0=1
fib(3), N=3
Devuelve 1
Llama a
fib(2), N=2

Llama a
fib(2), N=2
Devuelve 0
fib(1), N=1

Devuelve 1

Llama a

fib(2), N=2

fib(1), N=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 <= 3)
return N;
else if (N % 2 == 0)
return julianacci(N-1) + julianacci(N-2) + julianacci(N-3);
else
return julianacci(N-1) - julianacci(N-3);
}
}

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.

También podría gustarte