M.C. Yolanada Moyao Martínez
Es una técnica de programación que permite que un bloque de instrucciones se ejecute n veces. En Java los métodos pueden llamarse a sí mismos. Si dentro de un método existe la llamada a sí mismo decimos que el método es recursivo. Llamado a si mismo Pila
Cuando un método se llama a sí mismo, se asigna espacio en la pila para las nuevas variables locales y parámetros. Al volver de una llamada recursiva, se recuperan de la pila variables locales, parámetros antiguos y la ejecución se reanuda en el punto de la llamada al método. Reanudar ejecución Variables locales Parámetros antiguos
Uno o más casos base: casos para los que existe una solución directa. Una o más llamadas recursivas: casos en los que se llama sí mismo
Los valores de los parámetros de entrada permiten al método devolver un resultado directo Ejemplo if (n==0) return 1;
El valor del parámetro en cada llamada se ha de modificar de forma que se aproxime cada vez más hasta alcanzar al valor del caso base. Ejemplo return n * ( factorial(n-1) );
public class Recursividad { void repetir() { repetir(); } public static void main(string[] ar) { Recursividad re=new Recursividad(); re.repetir(); }} Exception in thread "main" java.lang.stackoverflowerror at Recursividad.repetir(Recursividad.java:4) at Recursividad.repetir(Recursividad.java:4) at Recursividad.repetir(Recursividad.java:4) at Recursividad.repetir(Recursividad.java:4) at Recursividad.repetir(Recursividad.java:4)
public class Recursividad { void imprimir(int x) { System.out.println(x); imprimir(x-1); } public static void main(string[] ar) { Recursividad re=new Recursividad(); re.imprimir(5); } } 4 bytes de x -6190-6191 4 bytes por Exception in thread "main" java.lang.stackoverflowerror llamado at sun.nio.cs.singlebyte.withresult(singlebyte.java:44) at sun.nio.cs.singlebyte.access$000(singlebyte.java:38) at sun.nio.cs.singlebyte$encoder.encodearrayloop(singlebyte.java:187) at sun.nio.cs.singlebyte$encoder.encodeloop(singlebyte.java:219)
public class Recursividad { void imprimir(int x) { if (x>0) { System.out.println(x); imprimir(x-1); } } public static void main(string[] ar) { Recursividad re=new Recursividad(); re.imprimir(5); } } 5 4 3 2 1 Process completed. Imprime del 5 al 1
public class Recursividad { void imprimir(int x) { if (x>0) { imprimir(x-1); System.out.println(x);} } public static void main(string[] ar) { Recursividad re=new Recursividad(); re.imprimir(5); } } 1 2 3 4 5 Process completed. Imprime del 1 al 5
.. System.out.println(x); Imprime del 1 al 5
public class Recursividad { int factorial(int fact) { if (fact>0) { int valor=fact * factorial(fact-1); return valor; } else return 1; } public static void main(string[] ar) { Recursividad re=new Recursividad(); int f=re.factorial(4); System.out.println("El factorial de 4 es "+f); } } Factorial
.
import java.util.*; public class Recursividad1 { public static void main(string[] args) { Scanner sc = new Scanner(System.in); int n1, n2; System.out.print("Introduzca primer numero: "); n1 = sc.nextint(); System.out.print("Introduzca segundo numero: "); n2 = sc.nextint(); System.out.println("suma: " + suma(n1, n2)); } public static int suma(int a, int b) { if (b == 0) { return a; } else if (a == 0) { return b; } else { return 1 + suma(a, b - 1); } }
Más lentos Más memoria Soluciones recursivas son más lentas que las iterativas por el tiempo empleado en la gestión de las sucesivas llamadas a los métodos. Más memoria ya que se deben guardar los contextos de ejecución de cada método que se llama. En ciertos problemas, la recursividad conduce a soluciones que son mucho más fáciles de leer y comprender que su correspondiente solución iterativa. Más fáciles
Hacer un programa con un método recursivo para calcular m elevado a n siendo n y m número entero mayor o igual que 0. Hacer un programa con un método recursivo que calcula la suma de dos números enteros. Hacer un programa con un método para ordenar un arreglo recursivamente.
Simple: Solo se tiene una llamada recursiva Indirecta: Desde otro método se realiza el llamado Múltiple: Más de un llamado al método dentro del cuerpo del mismo. Anidada: Como parte de los parámetros se realiza el llamado al método
public static boolean impar (int n) { if (n==0) return false; else return par(n-1); } public static boolean par (int n) { if (n==0) return true; else return impar(n-1); } par impar
public class FibonacciRecursivo{ public static long FiboRecursivo(long pos){ long retornado=0; if(pos==0 pos==1){ retornado=pos; }else{ Más de 1 llamado retornado=fiborecursivo(pos-2)+fiborecursivo(pos-1); } return retornado; } public static void main(string args[]){ System.out.println(FiboRecursivo(3)); } }
= 3 2 1 1 0
public static long mor(int n, m){ if (n==m) return (m+1); else return mor(n,mor(n-1,m+1)); } 1 llamado como parámetro
mor(4,0) = mor(4,mor(3,1)) = mor(4,mor(3,mor(2,2)) = mor(4,mor(3,3)) = mor(4,4) = 5
public static long ack (int n, m) { if (n==0) return (m+1); else if (m==0) return ack(n-1,1); else return ack(n-1,ack(n,m-1)); }
Dado un arreglo constituido de números enteros y que contiene N elementos siendo N >= 1, escribir un método que devuelva la suma de todos los elementos mayores que el último elemento del arreglo. Dado un arreglo constituido de números enteros y que contiene N elementos siendo N >= 1, escribir un método que devuelva cierto si la suma de la primera mitad de los enteros del arreglo es igual a la suma de la segunda mitad de los enteros del arreglo. Nota: para resolver los ejercicios basta con hacer un único recorrido sobre el arreglo. Tampoco debe utilizarse ningún arreglo auxiliar, pero si se podrán utilizar variables de tipo entero o booleano.
Dados dos arreglos A y B de longitud n y m respectivamente, n >= m cuyos elementos estén ordenados y no se repiten, hacer un método que determine si todos los elementos de B están contenidos en A. Recordar que los elementos están ordenados, de esta manera basta con realizar un único recorrido sobre cada arreglo. Hacer un programa que resuelva el juego de las torres de Hanoi de forma recursiva