O (1): Código simple sin bucles. Simplemente fluye. Las búsquedas en una tabla de búsqueda también son O (1).
O (log (n)): algoritmos optimizados de manera eficiente. Ejemplo: algoritmos de árbol binario y búsqueda binaria. Usualmente no duele Tienes suerte si tienes ese algoritmo a mano.
O (n): un solo bucle de datos. Duele por muy grande n.
O (n * log (n)): un algoritmo que hace una especie de estrategia de dividir y conquistar. Duele por grande n. Ejemplo típico: merge sort
O (n * n): un bucle anidado de algún tipo. Duele incluso con pequeñas n. Común con cálculos de matriz ingenua. Desea evitar este tipo de algoritmo si puede.
O (n^x for x> 2): una construcción perversa con múltiples bucles anidados. Duele por muy pequeño n.
O (x^n, n! Y peores): algoritmos extravagantes (ya menudo recursivos) que no desea tener en el código de producción excepto en casos muy controlados, para n muy pequeños y si realmente no hay mejor alternativa. El tiempo de cálculo puede explotar con n = n + 1.
Al mover su algoritmo hacia abajo desde una clase de mayor complejidad puede hacer que su algoritmo vuele. Piense en la transformación de Fourier que tiene un algoritmo O (n * n) que no se puede usar con el hardware de los años 60 excepto en casos excepcionales. Luego Cooley y Tukey hicieron algunas reducciones inteligentes de complejidad al reutilizar los valores ya calculados. Eso condujo a la introducción generalizada de FFT en el procesamiento de señales. Y al final también es la razón por la cual Steve Jobs hizo una fortuna con el iPod.
ejemplo simple: los programadores de C Naive escribir este tipo de bucle:
for (int cnt=0; cnt < strlen(s) ; cnt++) {
/* some code */
}
Eso es un O (n * n) algoritmo debido a la aplicación de strlen(). Los bucles de anidación conducen a la multiplicación de complejidades dentro de la gran O. O (n) dentro de O (n) da O (n * n). O (n^3) dentro de O (n) da O (n^4). En el ejemplo, el precalculo de la longitud de la cuerda convertirá inmediatamente el ciclo en O (n). Joel has also written about this.
Sin embargo, la clase de complejidad no es todo. Tienes que vigilar el tamaño de n. Volver a trabajar un algoritmo O (n * log (n)) a O (n) no ayudará si el número de instrucciones (ahora lineales) crece masivamente debido a la reelaboración. Y si n es pequeño de todos modos, la optimización no dará mucho golpe, también.
En resumen, algunas personas escriben código que es basura, pero ni siquiera pueden comprender por qué es basura. La notación Big-O puede ser una ayuda para hacerles saber que junto con la notación que desconocen, es un efecto de ralentización del tiempo de ejecución del mundo real de su código, que depende de la longitud de n en este caso (variable en tiempo de ejecución), que no entienden que el código comienza mal y empeora a medida que crece el tamaño de su conjunto de datos. –