NOMBRE: DARWIN MAGUANA
¿Qué es la notación Big O?
Definición
La notación Big O es la representación relativa de la complejidad de un algoritmo.
¿Qué significa?
representación: Big O trata de simplificar la comparación entre algoritmos a una sola variable
relativa: esta comparación solo tiene sentido si se trata de algoritmos similares, no sirve de
mucho comparar un algoritmo de búsqueda con un algoritmo de ordenamiento.
complejidad: ¿cómo se comporta el algoritmo cuando la entrada de datos aumenta?, ¿necesita
más memoria? ¿necesita más tiempo?
Diferentes complejidades
En la siguiente sección veremos diferentes complejidades para los algoritmos, esta no es una lista
exhaustiva, pero contiene las complejidades más habituales.
O(1) Complejidad Constante
Significa que la cantidad de datos es irrelevante para el algoritmo, siempre va a tardar el mismo
tiempo en terminar. Lamentablemente es difícil que un algoritmo no trivial caiga en esta categoría.
Items Tiempo
1 k segundos
10 k segundos
100 k segundos
Asumiendo que k es una cantidad constante
Ejemplos
–Acceder al elemento de un arreglo
–Insertar en elemento en una lista ligada
–Añadir o sacar un elemento de una pila
O(log n) Complejidad Logarítmica
En este caso el tiempo incrementa conforme aumenta el número de elementos, pero de forma
logarítmica por lo que para grandes cantidades de datos el tiempo es relativamente corto.
Items Tiempo
1 1 segundo
10 2 segundos
100 3 segundos
1000 4 segundos
10000 5 segundos
Ejemplos
–Búsqueda binaria
–Encontrar menor/mayor elemento en un árbol binario de búsqueda
–Algunos algoritmos Divide y Vencerás
Divide y Vencerás
O(n) Complejidad Lineal
¿Vas a incrementar la cantidad de elementos? Seguro, pero el tiempo va a incrementar de forma
proporcional.
Items Tiempo
1 1 segundo
10 10 segundos
100 100 segundos
Ejemplos
–Recorrer un arreglo o lista ligada
–Búsqueda lineal
–Comparar dos cadenas
O(n log n)
Esta es una combinación de las dos anteriores, es común encontrar varios algoritmos de
ordenamiento en esta categoría.
Items Tiempo
1 1 segundo
10 20 segundos
100 300 segundos
Ejemplos
–Merge Sort
–Heap Sort
–Quick Sort
O(n^2) Complejidad Cuadrática
La cantidad de tiempo que tarda el algoritmo comienza a dispararse, no es muy eficiente con una
gran cantidad de datos.
Items Tiempo
1 1 segundo
10 100 segundos
100 10000 segundos
Ejemplos
–Bubble sort
–Selection sort
–Iterar un arreglo de 2 dimensiones
Consideraciones
Ahora veamos qué sucede cuando un algoritmo no se representa exactamente en una de las
categorías anteriores, por ejemplo: O(n + 2)
Aquí sólo nos interesa O(n), porque conforme el número de elementos aumente la constante 2 será
cada vez más insignificante.
Lo mismo ocurriría con una complejidad como O(n^2 + 2n + 1). Donde solo tomamos en cuenta la
potencia más grande O(n^2)
Al analizar un algoritmo existen tres casos comunes:
–Mejor caso (best case)
–Caso promedio (average case)
–Peor caso (worst case)
Generalmente el más representativo es el peor caso porque nos indica la categoría de
complejidad más alta de un algoritmo, para entender esto considera un algoritmo de búsqueda
lineal, su complejidad es O(n) por lo tanto en el peor de los casos tenemos que recorrer todo el
arreglo, en el caso promedio solo la mitad de elementos O(n/2), y en el peor de los casos el primer
elemento es el que buscamos O(1).
¿Por qué es importante?
Con el poder computacional que tenemos hoy en día un algoritmo que tenga como entrada un
grupo de datos pequeño o mediano puede terminar en un tiempo aceptable, sin embargo si no
analizamos su complejidad no estaremos seguros si el algoritmo funcionará con un grupo de datos
grande (como algunos millones de datos).
A la capacidad de un algoritmo de manejar correctamente un aumento continuo de entradas se le
llama escalabilidad.
Por ejemplo, supongamos que has desarrollado dos algoritmos de ordenamiento y quieres
comparar su tiempo de ejecución, a cada uno le das una entrada de 1000 elementos y el algoritmo
1 (A1) tarda 5 segundos, mientras que el algoritmo 2 (A2) tarda 9 segundos. ¿Es mejor el
algoritmo 1? Tal vez, pero aún no podemos estar tan seguros.
Después de analizar su complejidad resulta que el A1 es n log n y el A2 es log n, en un principio tal
vez A2 sea más lento, pero cuando el número de elementos sea lo suficientemente grande A2
será más rápido que A1, es decir, va a escalar mejor.
Conclusión
El análisis de la complejidad de un algoritmo debe ser una habilidad básica de cualquier
desarrollador porque permite escribir programas que son más eficientes y escalables a largo
plazo.
Una buena forma de practicar es revisar código escrito por nosotros mismos o por alguna
biblioteca y tratar de obtener la complejidad de métodos o funciones, también la próxima vez que
hagamos un programa nos podemos detener unos minutos para analizarlo.