Recursividad en Java
Nivel 8 · 40 min · 3 preguntas

Terreno avanzado

Recursion mutua, limites reales y cuando no usarla.

La idea en una frase

La recursion es segura cuando la profundidad crece mucho mas despacio que el dato. Si crece igual, es una bomba de tiempo.

Antes de ver codigo

Una escalera de mano de tres metros sirve para casi todo en una casa. La misma escalera en un edificio de veinte pisos no es "un poco corta": es la herramienta equivocada. La pregunta no es si la recursion es bonita, sino que tan alto va a tener que subir con los datos reales.

Recursion mutua

Dos metodos que se llaman entre si. No hay ninguna magia extra: la pila alterna marcos de uno y de otro. Aparece de forma natural en analizadores sintacticos, donde expresion() llama a termino() y termino() vuelve a llamar a expresion() dentro de un parentesis.

static boolean esPar(int n) {
    if (n == 0) return true;
    return esImpar(n - 1);
}

static boolean esImpar(int n) {
    if (n == 0) return false;
    return esPar(n - 1);
}

El tamano real de la pila

El limite no se mide en llamadas sino en bytes. Un metodo con muchas variables locales tiene marcos mas grandes y revienta antes. Puedes medirlo tu mismo con un contador y un try-catch de StackOverflowError.

El flag -Xss cambia el tamano de pila por hilo: java -Xss4m MiPrograma. Ojo: es por hilo, asi que en un servidor con miles de hilos multiplicar ese valor tiene un costo enorme.

static int profundidad = 0;

static void medir() {
    profundidad++;
    medir();
}

public static void main(String[] args) {
    try {
        medir();
    } catch (StackOverflowError e) {
        System.out.println("Reventó en: " + profundidad);
    }
}

Cuando NO usar recursion

Un buen profesor tambien ensena a no usar la herramienta. No uses recursion cuando la profundidad depende del tamano del dato de entrada y ese dato puede ser grande. Recorrer una lista enlazada de un millon de nodos de forma recursiva es un error, aunque quede bonito.

Si el arbol esta balanceado la profundidad es log n y la recursion es perfectamente segura. Si el arbol puede degenerar en una linea, no lo es. Esa es la pregunta que hay que hacerse.

Recursion indirecta escondida

Un ciclo A llama a B, B llama a C, C llama a A puede colarse en cualquier proyecto grande sin que nadie lo note, hasta que en produccion llega un dato que lo dispara. Cuando veas un StackOverflowError con un rastro que se repite en bloque, es esto.

Ejecuta y observa

Aqui es donde la teoria de arriba se vuelve concreta. Cambia los parametros, dale a Reproducir, y sobre todo usa las flechas para ir paso a paso: la velocidad automatica sirve para ver la forma general, pero lo que de verdad ensena es detenerse en un retorno y entender por que vuelve ahi y no a otro lado.

Errores que vas a cometer

No son ejemplos inventados: son los que aparecen una y otra vez en los parciales. Lee el codigo, decide tu mismo que esta mal, y solo despues abre la correccion. Si la abres de una, no aprendes nada.

Recursion sobre datos de tamano ilimitado

static int contar(Nodo n) {
    if (n == null) return 0;
    return 1 + contar(n.siguiente);
}

Comprueba lo que entendiste

Responde sin devolverte a leer. Si fallas no pasa nada: la explicacion te dice exactamente donde estaba el hueco, y ese es el momento en que de verdad se aprende. Con el 70% el nivel queda aprobado.