Clase Teorica 03

10

Click here to load reader

description

Clase Practica del curso de Estructuras De Datos de la Universidad Nacioanl Sede Medellin. Este curso hace parte de la malla curricular del Plan de Estudio de la Carrera Ingenieria de Sistemas.

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.