Ejercicios Prácticos de Complejidad Algorítmica II
Esta segunda sesión de ejercicios prácticos se centra en el análisis de complejidad espacial (consumo de memoria dinámica en el Heap y marco de llamadas en el Stack) y en algoritmos recursivos frente a iterativos.
1. Claves para el Análisis de Complejidad Espacial #
La complejidad espacial evalúa la memoria adicional que requiere un algoritmo en función del tamaño de entrada :
- Espacio Constante (): Variables escalares auxiliares (
int sum = 0;, punteros simples) independientemente de . - Espacio Lineal (): Creación de nuevos arrays, listas o estructuras proporcionales a , o bien llamadas recursivas activas en la pila de ejecución (Call Stack).
- Espacio Exponencial ( o ): Árboles recursivos profundos sin poda o matrices bidimensionales .
2. Comparativa: Recursión Clásica vs Optimización Iterativa #
1# Caso 1: Fibonacci recursivo ingenuo -> Tiempo O(2^n), Espacio Stack O(n) 2def fibonacci_recursivo(n): 3 if n <= 1: 4 return n 5 return fibonacci_recursivo(n - 1) + fibonacci_recursivo(n - 2) 6 7 # Caso 2: Fibonacci iterativo optimizado -> Tiempo O(n), Espacio O(1) 8def fibonacci_iterativo(n): 9 if n <= 1: 10 return n 11 a, b = 0, 1 12 for _ in range(2, n + 1): 13 a, b = b, a + b 14 return b
Resumen del tema
Conceptos clave #
- Consumo de Pila (Call Stack): cada llamada recursiva pendiente ocupa un marco de memoria en la pila del hilo.
- Trade-off Espacio vs Tiempo: técnicas como la memoización o programación dinámica aumentan el espacio () para reducir drásticamente el tiempo de exponencial a lineal ().
- Variables Acumuladoras: sustituir estructuras intermedias por variables escalares reduce la complejidad espacial a .
Qué debes recordar #
Siempre evalúa tanto la memoria estática reservada en el Heap como la profundidad máxima de llamadas en el Stack de recursión.