Recursion: functions that call themselves
Base case, recursive case and the call stack, with a visualiser of factorial, Fibonacci and Towers of Hanoi.
A recursive function solves a problem by solving a smaller version of the same problem, until it reaches a case so simple it answers directly. It sounds odd; with the call stack in front of you it becomes clear.
The two parts of every recursion
- Caso base: la condición que corta la recursión. Sin él, la función se llama para siempre → stack overflow.
- Caso recursivo: la función se llama a sí misma con un problema más pequeño, acercándose al caso base.
function factorial(n) {
if (n <= 1) return 1; // caso base
return n * factorial(n - 1); // caso recursivo
}
Call stack visualiser
Cada llamada pendiente es un marco apilado. Cuando una llamada devuelve, su marco se quita y el de abajo continúa. Elige una función y pulsa Ejecutar:
Careful with recursive Fibonacci
fib(n) = fib(n-1) + fib(n-2) es elegante pero recalcula lo mismo una y otra vez: es O(2ⁿ). fib(40) ya tarda segundos. Se arregla guardando resultados (memoización) o con un bucle:
function fib(n, memo = {}) {
if (n < 2) return n;
if (memo[n]) return memo[n];
return memo[n] = fib(n - 1, memo) + fib(n - 2, memo); // ahora O(n)
}
Recursion vs loop
Todo lo recursivo se puede escribir con un bucle y viceversa. La recursión brilla cuando la estructura del problema ya es recursiva: árboles, carpetas dentro de carpetas, dividir y vencer.
# Recorrer una carpeta y sus subcarpetas: natural con recursión
import os
def listar(ruta, nivel=0):
for nombre in sorted(os.listdir(ruta)):
completa = os.path.join(ruta, nombre)
print(" " * nivel + nombre)
if os.path.isdir(completa):
listar(completa, nivel + 1) # el mismo problema, una carpeta más adentro
Check what you've learned
factorial(n) = n <= 1 ? 1 : n * factorial(n-1), ¿cuánto es factorial(4)?