ESTRUCTURAS DE DATOS Recursión
Recursión Una función recursiva es aquella que se llama a sí
misma. Permite que la misma función se repita con valores
diferentes de parámetros. Es una alternativa a la iteración, provee una solución
elegante a problemas, que tienen naturaleza recursiva. Normalmente, una solución recursiva es menos eficiente
en términos de tiempo de computadora que una solución iterativa debido al tiempo adicional de llamada a procedimientos.
En muchos casos permite especificar una solución mas simple y natural para resolver un problema que en otro caso seria difícil
Tipos de recursión
Recursión directa. Cuando el código F tiene una sentencia que involucra a F.
Recursión indirecta o cruzada.- Cuando la función F involucra una función G que invoca a la ves una función H, y así sucesivamente, hasta que se involucra la función F.
Ejemplo de recursión directapublic class Main {
public static int Factorial(int n){ if (n==0)return 1; return n*Factorial(n-1); } public static void main(String[] args) { int n=6; for (int i=0;i<=n;i++) System.out.println(i+"! ="+Factorial(i));
}
}
Ejemplo de recursión indirecta
int par(int n) { if (n == 0) return 1; return impar(n-1);
} int impar(int n) { if (n == 0) return 0;return par(n-1);
}
public class Main { public static boolean par(int n) {
if (n == 0) return true;return impar(n-1);
} public static boolean impar(int n) {
if (n == 0) return false;return par(n-1);
} public static void main(String[] args) { int n = 10; for (int i=0;i<=n;i++) if (par(i)) System.out.println(i+" es par"); else System.out.println(i+" no es par"); for (int i=0;i<=n;i++) if (impar(i)) System.out.println(i+" es impar"); else System.out.println(i+" no es impar"); }}
Tipos de recursión Recursión simple: Aquella en cuya función solo aparece una llamada
recursiva. Se puede transformar con facilidad en algoritmos iteractivos. Recursión múltiple: Se da cuando hay más de una llamada a sí misma
dentro del cuerpo de la función, resultando más difícil de transformar a iteractiva.
Por ejemplo el algoritmo de Fibonacci.
int fibonacci(int n) {
if (n<=1) return 1;return fibonacci(n-1) + fibonacci(n-2);
} Recursión anidada: En algunos de los argumentos de la llamada hay una
nueva llamada a sí misma.
Por ejemplo la función de Ackerman:
int Ack(int m, int n) {
if (m==0) return n+1; if (n==0) return Ack(m-1, 1);
return Ack(m-1, Ack(m, n-1)); }
Condiciones de terminación Debe asegurarse que el algoritmo está
bien definido, para que no vaya a terminar en una recursión que no termine.
Para garantizar que el algoritmo termine se debe de cumplir que el argumento de la función vaya decrementando y que haya un valor de definición
Ejemplos: Factorial
n! = 1, para n=0
n! = n * (n-1)!, para n>0 Ackermann
A(m,n) = n+1, para m=0
A(m,n) = A(m-1,1), para m>0 y n=0
A(m,n) = A(m-1,A(m,n-1)), para m>0 y n>o
Torres de HanoiSe trata de mover n discos de una torre A a otra torre C, auxiliándose de la torre B. Sólo se puede tomar un disco a la vez, y debe ser el que está en el tope. No se puede colocar un disco encima de uno más pequeño.
Algoritmo: Mover n discos de origen a destino, usando una torre auxiliar Si n=1, mueva el disco del origen al
destino Si n>1
○ Mueva n-1 discos de origen a auxiliar (usando destino como auxiliar), usando el mismo algoritmo.
○ Mueva el disco n, de inicial a destino.○ Mueva n-1 discos de auxiliar a destino
(usando origen como auxiliar), usando el mismo algoritmo.
Recursión con retroceso
Son algoritmos “elegantes“, para resolver problemas complicados, que por el uso de recursión se obtienen algoritmos simples.
Consisten en probar soluciones hasta encontrar la correcta(prueba y error).
Ejemplos de recursión con retroceso El problema de las ocho reinas
http://introcs.cs.princeton.edu/java/23recursion/Queens.java.html El problema del caballo viajero Los matrimonios estables Laberinto