Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Problema 1:
Implementacin de un mtodo recursivo.
Programa:
publicclassRecursividad{
voidrepetir(){
repetir();
}
publicstaticvoidmain(String[]ar){
Recursividadre=newRecursividad();
re.repetir();
}
}
La funcin repetir es recursiva porque dentro de la funcin se llama a s misma.
Cuando ejecuta este programa se bloquear y generar una excepcin:
"Exception in thread "main" java.lang.StackOverflowError"
Analicemos
como
funciona:
Primero se ejecuta la funcin main, luego de crear un objeto llamamos a la
funcin
repetir.
Hay que tener en cuenta que cada vez que se llama a una funcin se reservan
4 bytes de la memoria que se liberarn cuando finalice su ejecucin.
La primera lnea de la funcin llama a la funcin repetir, es decir que se
reservan 4 bytes nuevamente. Se ejecuta nuevamente una instancia de la
Problema 2:
Implementacin de un mtodo recursivo que reciba un parmetro de tipo entero
y luego llame en forma recursiva con el valor del parmetro menos 1.
Programa:
publicclassRecursividad{
voidimprimir(intx){
System.out.println(x);
imprimir(x1);
}
publicstaticvoidmain(String[]ar){
Recursividadre=newRecursividad();
re.imprimir(5);
}
}
Desde la main se llama a la funcin imprimir y se le enva el valor 5. El
parmetro x recibe el valor 5. Se ejecuta el algoritmo de la funcin, imprime el
contenido del parmetro (5) y seguidamente se llama a una funcin, en este
caso a s misma (por eso decimos que es una funcin recursiva), envindole el
valor
4.
El parmetro x recibe el valor 4 y se imprime en pantalla el cuatro, llamando
nuevamente
a
la
funcin
imprimir
envindole
el
valor
3.
Si continuamos este algoritmo podremos observar que en pantalla se imprime:
5 4 3 2 1 0 ?1 ?2 ?3 . . . . . . . . .
hasta
que
se
bloquee
el
programa.
Tener en cuenta que cada llamada a una funcin consume 4 bytes por la
llamada y en este caso 4 bytes por el parmetro x. Como nunca finaliza la
ejecucin completa de las funciones se desborda la pila esttica por las
sucesivas llamadas.
Problema 3:
Implementar un mtodo recursivo que imprima en forma descendente de 5 a 1
de uno en uno.
Programa:
publicclassRecursividad{
voidimprimir(intx){
if(x>0){
System.out.println(x);
imprimir(x1);
}
}
publicstaticvoidmain(String[]ar){
Recursividadre=newRecursividad();
re.imprimir(5);
}
}
Ahora si podemos ejecutar este programa y observar los resultados en
pantalla. Se imprimen los nmeros 5 4 3 2 1 y no se bloquea el programa.
Analice qu sucede cada vez que el if (x>0) se evala como falso, a qu lnea
del programa retorna?
Problema 4:
Imprimir los nmeros de 1 a 5 en pantalla utilizando recursividad.
Programa:
publicclassRecursividad{
voidimprimir(intx){
if(x>0){
imprimir(x1);
System.out.println(x);
}
}
publicstaticvoidmain(String[]ar){
Recursividadre=newRecursividad();
re.imprimir(5);
}
}
Con este ejemplo se presenta una situacin donde debe analizarse lnea a
lnea la ejecucin del programa y el porque de estos resultados.
Por qu se imprime en pantalla 1 2 3 4 5 ?
Veamos como se apilan las llamadas recursivas:
void imprimir(int x) {
if (x>0) {
imprimir(x-1);
System.out.println(x);
}
}
Cuando x vale 0 la condicin del if se vala como falsa y sale de la funcin
imprimir.
Qu
lnea
ahora
se
ejecuta
?
Vuelve a la funcin main ? NO.
Recordemos que la ltima llamada de la funcin imprimir se haba hecho desde
la misma funcin imprimir por lo que vuelve a la lnea:
System.out.println(x);
Ahora si analicemos que valor tiene el parmetro x. Observemos la pila de
llamadas del grfico:
Problema 5:
Otro problema tpico que se presenta para analizar la recursividad es el obtener
el
factorial
de
un
nmero.
Recordar que el factorial de un nmero es el resultado que se obtiene de
multiplicar dicho nmero por el anterior y as sucesivamente hasta llegar a uno.
Ej. el factorial de 4 es 4 * 3 * 2 * 1 es decir 24.
Programa:
publicclassRecursividad{
intfactorial(intfact){
if(fact>0){
intvalor=fact*factorial(fact1);
returnvalor;
}else
return1;
}
publicstaticvoidmain(String[]ar){
Recursividadre=newRecursividad();
intf=re.factorial(4);
System.out.println("Elfactorialde4
es"+f);
}
}
La funcin factorial es recursiva porque desde la misma funcin llamamos a la
funcin
factorial.
Debemos hacer el seguimiento del problema para analizar como se calcula.
La memoria en la primera llamada:
fact recibe el valor 4 y valor se cargar con el valor que se obtenga con el
producto de fact por el valor devuelto por la funcin factorial (llamada recursiva)
Cuando fact recibe un cero la condicin del if se vala como falsa y ejecuta el
else retornando un 1, la variable local de la llamada anterior a la funcin queda
de la siguiente manera:
Problema 6:
Implementar un mtodo recursivo para ordenar los elementos de un vector.
Programa:
classRecursivdad{
staticint[]vec={312,614,88,22,54};
voidordenar(int[]v,intcant){
if(cant>1){
for(intf=0;f<cant1;f+
+)
if(v[f]>v[f+1]){
intaux=v[f];
v[f]=v[f+1];
v[f+1]=aux;
}
ordenar(v,cant1);
}
}
voidimprimir(){
for(intf=0;f<vec.length;f++)
System.out.print(vec[f]+"");
System.out.println("\n");
publicstaticvoidmain(String[]ar){
Recursivdadr=newRecursivdad();
r.imprimir();
r.ordenar(vec,vec.length);
r.imprimir();
}
}
Hasta ahora hemos visto problemas que se pueden resolver tanto con
recursividad
como
con
estructuras
repetitivas.
Es muy importante tener en cuenta que siempre que podamos emplear un
algoritmo no recursivo ser mejor (ocupa menos memoria de ram y se ejecuta
ms
rpidamente)
Pero hay casos donde el empleo de recursividad hace mucho ms sencillo el
algoritmo (tener en cuenta que no es el caso de los tres problemas vistos
previamente)