Está en la página 1de 12

RECURSIVIDAD

PROGRAMACION ORIENTADA A OBJETOS 2


¿QUÉ ES RECURSIVIDAD?

Primero debemos decir que la recursividad no es una estructura de datos, sino que es una técnica de programación
que nos permite que un bloque de instrucciones se ejecute n veces. Remplaza en ocasiones a estructuras repetitivas.

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.

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 las variables locales y los parámetros antiguos y la
ejecución se reanuda en el punto de la llamada al método.

En general, la recursividad es el proceso de definir algo en términos de sí mismo y es algo similar a una definición
circular. El componente clave de un método recursivo es una declaración que ejecuta una llamada a sí mismo. La
recursividad es un poderoso mecanismo de control.
EJEMPLO 1.

• Implementación de un método recursivo.

public class Recursividad {

void repetir() {
repetir();
}

public static void main(String[] ar) {


Recursividad re=new Recursividad();
re.repetir();
}
}
EJEMPLO 1.

La función repetir es recursiva porque dentro de la función se llama a sí misma.


Cuando ejecuta este programa se bloqueará y generará una excepción: "Exception in thread "main"
java.lang.StackOverflowError"

Analicemos como funciona:

1. Primero se ejecuta la función main, luego de crear un objeto llamamos a la función repetir.
2. Hay que tener en cuenta que cada vez que se llama a una función se reservan bytes de la memoria que se
liberarán cuando finalice su ejecución.
2. La primera línea de la función llama a la función repetir, es decir que se reservan bytes nuevamente.
3. Se ejecuta nuevamente una instancia de la función repetir y así sucesivamente hasta que la pila estática se colme
y se cuelgue el programa.
EJEMPLO 2.

• Implementación de un método recursivo que reciba un parámetro de tipo entero y luego llame en forma recursiva
con el valor del parámetro menos 1.

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);
}
}
EJEMPLO 2.

1. Desde el main se llama a la función imprimir y se le envía el valor 5.


2. El parámetro x recibe el valor 5.
3. Se ejecuta el algoritmo de la función, imprime el contenido del parámetro (5) y seguidamente se llama a una
función, en este caso a sí misma (por eso decimos que es una función recursiva), enviándole el valor 4.
4. El parámetro x recibe el valor 4 y se imprime en pantalla el cuatro, llamando nuevamente a la función imprimir
enviándole 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 función consume 4 bytes por la llamada y en este caso 4 bytes por el
parámetro x. Como nunca finaliza la ejecución completa de las funciones se desborda la pila estática por las sucesivas
llamadas.
EJEMPLO 3.

• Implementar un método recursivo que imprima en forma descendente de 5 a 1 de uno en uno..

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);
}
}
EJEMPLO 3.

1. Podemos ejecutar este programa y observar los resultados en pantalla.


2. Se imprimen los números 5 4 3 2 1 y no se bloquea el programa.
EJEMPLO 4.

Cálculo del factorial de un número.


El factorial de un número N es el producto de todos los números enteros que se encuentren entre 1 y N.
Por ejemplo, el factorial de 3 es 1 × 2 × 3, es decir, es 6.

El siguiente programa muestra una forma recursiva de calcular el factorial de un número.


EJEMPLO 4.

class Factorial
{
// Esto es un método recursivo
int facR (int n){
int resultado;
if (n==1) return 1;
resultado=facR(n-1)*n;
return resultado;
}
}

class Recursividad{
public static void main(String[] args) {
Factorial f= new Factorial();
System.out.println("Factorial utilizando un método recursivo:");
System.out.println("El factorial de 3 es: "+f.facR(3));
System.out.println("El factorial de 6 es: "+f.facR(6));
}
}
DESBORDAMIENTO DE PILA (STACK OVERFLOW)

Las versiones recursivas de muchas rutinas pueden ejecutarse un poco más lentamente que sus equivalentes iterativos debido a la sobrecarga
adicional de las llamadas a métodos adicionales. Demasiadas llamadas recursivas a un método podrían causar un desbordamiento de la pila.

Como el almacenamiento para los parámetros y las variables locales está en la pila y cada llamada nueva crea una nueva copia de estas variables, es
posible que la pila se haya agotado. Si esto ocurre, el sistema de tiempo de ejecución (run-time) de Java causará una excepción. Sin embargo,
probablemente no tendrás que preocuparte por esto a menos que una rutina recursiva se vuelva loca.

La principal ventaja de la recursividad es que algunos tipos de algoritmos se pueden implementar de forma más clara y más recursiva de lo que pueden
ser iterativamente. Por ejemplo, el algoritmo de clasificación Quicksort es bastante difícil de implementar de forma iterativa. Además, algunos
problemas, especialmente los relacionados con la IA, parecen prestarse a soluciones recursivas.

int fact(int n)
{
// condición base equivocada (esto causa stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
DESBORDAMIENTO DE PILA (STACK OVERFLOW)

Al escribir métodos recursivos, debe tener una instrucción condicional, como un if, en algún lugar para forzar el retorno del método sin que se ejecute la
llamada recursiva.

Si no lo hace, una vez que llame al método, nunca retornará. Este tipo de error es muy común cuando se trabaja con recursividad. Use las
declaraciones println() generosamente para que pueda ver lo que está pasando y abortar la ejecución si ve que ha cometido un error.

También podría gustarte