Saltar al contenido principal
La notación asintótica dice cómo se expresa el coste de un algoritmo. Este tema es la parte práctica: cómo se mira un código y se calcula su complejidad. Con unas pocas reglas para bucles, llamadas y recursión se analiza casi cualquier programa, y se puede predecir si tardará un milisegundo o un año con un millón de datos.

Lo que vas a aprender

  • Qué cuenta como operación elemental.
  • Las reglas para secuencias, condicionales y bucles.
  • Los bucles anidados, dependientes y logarítmicos.
  • Cómo analizar la recursión.
  • El coste oculto de las operaciones de las estructuras de datos.
  • La complejidad espacial.

Fundamentos teóricos

Operaciones elementales

Las que tardan un tiempo constante, O(1)O(1): asignaciones, operaciones aritméticas, comparaciones, acceso a un elemento de un array por índice, llamar a una función (sin contar lo que hace dentro).

Reglas básicas

Bucles típicos

La clave de los bucles logarítmicos: la variable se multiplica o divide por una constante en cada vuelta, en lugar de sumar.

Recursión

Se escribe una recurrencia con el coste de cada llamada y el de las llamadas que hace: Las del tipo aT(n/b)+O(nk)aT(n/b) + O(n^k) se resuelven con el teorema maestro (ver divide y vencerás).

El coste oculto de las estructuras de datos

Una sola línea puede esconder un bucle:

Complejidad espacial

La memoria adicional que usa el algoritmo. Una lista auxiliar de tamaño nn es O(n)O(n); una matriz n×nn\times n, O(n2)O(n^2). La recursión también ocupa memoria: cada llamada pendiente está en la pila, así que una recursión de profundidad nn usa O(n)O(n).

Qué tamaños son abordables

En un ordenador se hacen del orden de 10810^8–10910^9 operaciones sencillas por segundo:

Ejemplos resueltos

Ejemplo 1 · Dos bucles seguidos

O(n)+O(n2)=O(n2)O(n) + O(n^2) = O(n^2).
O(n2)O(n^2). Cambiando vistos = [] por vistos = set(), el in pasa a O(1)O(1) y el total a O(n)O(n): un cambio de una línea divide el tiempo por miles con muchos datos.
O(log⁡n)O(\log n): cuenta las cifras binarias de nn.
Vueltas: n+(n−1)+⋯+1=n(n+1)2n + (n-1) + \cdots + 1 = \frac{n(n+1)}{2}: O(n2)O(n^2), aunque haga la mitad de trabajo que dos bucles completos.
Parece O(n)O(n), pero a[1:] copia la lista: T(n)=T(n−1)+O(n)T(n) = T(n-1) + O(n), que da O(n2)O(n^2) en tiempo y O(n2)O(n^2) en memoria total copiada. Pasando un índice en lugar de rebanar, baja a O(n)O(n).
Un algoritmo O(n2)O(n^2) tarda 1 s con n=10 000n = 10\,000. Con n=100 000n = 100\,000: 102=10010^2 = 100 veces más, unos 100 s. Uno O(nlog⁡n)O(n\log n) que tarde 1 s con 10410^4 datos tardaría unos 12,5 s con 10510^5.

Errores frecuentes

  • Contar las líneas en vez de las vueltas. Un in, un sort o una rebanada en una línea pueden ser O(n)O(n) o más.
  • Multiplicar bucles que van uno detrás de otro. Se suman; solo se multiplican si están anidados.
  • Decir que un bucle de 1000 vueltas fijas es O(n)O(n). Si no depende de la entrada, es O(1)O(1).
  • Olvidar la memoria de la pila en la recursión.
  • Confundir el mejor caso con el coste del algoritmo. Se suele dar el peor caso.

Preguntas frecuentes

En la notación O no, pero en la práctica sí: un algoritmo O(n)O(n) con una constante enorme puede ser más lento que uno O(nlog⁡n)O(n\log n) para los tamaños reales. Por eso, para datos pequeños, inserción le gana a merge sort, y las bibliotecas combinan los dos. Lo definitivo es medir.
En Python, con el módulo timeit o con time.perf_counter() antes y después. Conviene probar con varios tamaños y ver cómo crece: si al duplicar nn el tiempo se cuadruplica, es cuadrático. El simulador de mejor y peor caso muestra esta idea.

Temas relacionados

Notación asintótica

O, Ω y Θ, y recurrencias.

Mejor y peor caso

Cuándo un algoritmo tarda más.

Búsqueda binaria

El ejemplo clásico de O(log n).
Última modificación el 12 de octubre de 2026