Recursividad en Java
Nivel 2 · 30 min

Antes y despues de la llamada

Lo que pasa al bajar no es lo que pasa al subir.

Dos momentos, no uno

Toda llamada recursiva parte el metodo en dos mitades. El codigo que esta antes de la llamada se ejecuta mientras la pila crece. El que esta despues se ejecuta mientras la pila se vacia, en orden inverso.

Este es el punto donde se atasca la mayoria. Cambiar una linea de lugar invierte el resultado completo.

static void bajando(int n) {
    if (n == 0) return;
    System.out.print(n + " ");   // ANTES
    bajando(n - 1);
}
// bajando(5)  ->  5 4 3 2 1

static void subiendo(int n) {
    if (n == 0) return;
    subiendo(n - 1);
    System.out.print(n + " ");   // DESPUES
}
// subiendo(5)  ->  1 2 3 4 5

Mismo metodo, misma condicion, mismo decremento. Solo cambio el orden de dos lineas y la salida se invirtio.

Por que se invierte

En subiendo(5), ninguna impresion ocurre hasta que la pila llega al fondo. Los cinco marcos quedan congelados justo antes de su print. Cuando el caso base retorna, se descongelan de arriba hacia abajo: primero el del 1, luego el del 2, y asi.

Regla practica: lo que escribes despues de la llamada recursiva sale al reves.

StackOverflowError

La pila tiene un tamano fijo, tipicamente 512 KB o 1 MB. Cuando se llena, la JVM lanza StackOverflowError. No es una excepcion normal: es un Error, y significa que agotaste memoria de pila, no memoria del heap.

En un metodo simple suele reventar entre 10.000 y 20.000 llamadas, pero depende del tamano de cada marco. Se puede ampliar con el flag -Xss4m, aunque eso casi siempre es tapar el sintoma.

Ejecuta y observa

Cambia los parametros, dale a Reproducir, y usa las flechas para avanzar paso a paso. La pila crece hacia arriba: el marco de arriba es el que se esta ejecutando ahora mismo.

Errores que vas a cometer

Lee el codigo, decide que esta mal, y despues abre la correccion.

Poner la impresion del lado equivocado

// Quiero imprimir 1..n en orden
static void contar(int n) {
    if (n == 0) return;
    System.out.print(n + " ");
    contar(n - 1);
}

Comprueba lo que entendiste

Necesitas el 70% para dar el nivel por visto. Responde sin devolverte a la teoria: si fallas, la explicacion te dice exactamente donde estaba el hueco.