Complejidad temporal T (n) = O (f (n)) y complejidad espacial S (n) = O (f (n))

Enlace original: https://blog.csdn.net/jsjwk/article/details/84315770

Algoritmo (Algoritmo) se refiere a un conjunto de métodos utilizados para manipular datos y resolver problemas de programa. Para el mismo problema, el uso de diferentes algoritmos puede terminar con el mismo resultado, pero los recursos y el tiempo consumidos en el proceso serán muy diferentes.

Entonces, ¿cómo debemos medir los pros y los contras de diferentes algoritmos?

Se considera principalmente a partir de las dos dimensiones de "tiempo" y "espacio" que ocupa el algoritmo.

Dimensión de tiempo: se refiere al tiempo consumido para ejecutar el algoritmo actual, usualmente usamos "complejidad de tiempo" para describirlo.

Dimensión espacial: se refiere a cuánto espacio de memoria se requiere para ejecutar el algoritmo actual, usualmente usamos "complejidad espacial" para describirlo.

Por lo tanto, evaluar la eficiencia de un algoritmo depende principalmente de su complejidad temporal y espacial. Sin embargo, a veces el tiempo y el espacio son "patas de pez y oso" y no pueden tener ambos, por lo que debemos lograr un equilibrio entre ellos.

Permítanme presentarles los métodos de cálculo de "complejidad temporal" y "complejidad espacial", respectivamente.

1. Complejidad del tiempo.
En la frecuencia de tiempo T (n), n representa la escala del problema. Cuando n sigue cambiando, T (n) seguirá cambiando en consecuencia. Para comprender la ley de este cambio, se introdujo el concepto de complejidad temporal. En general, el número de ejecuciones repetidas de esta operación basadas en el algoritmo es una función del tamaño del problema n, que es la frecuencia de tiempo T (n). Si hay una determinada función auxiliar f (n), cuando tiende a infinito, el valor límite de T (n) / f (n) es una cierta constante que no es cero, entonces f (n) es T (n) Las funciones del mismo orden de magnitud, denotadas como T (n) = O (f (n)), se denominan complejidad de tiempo asintótica del algoritmo, y también se las conoce como complejidad de tiempo para abreviar.

Por lo tanto, surgió otro método más general: "notación Big O", es decir, T (n) = O (f (n))
y O (n) para reflejar la notación del algoritmo, la complejidad del tiempo es Hay tres reglas para derivar el orden O grande llamado notación O grande
:
1. Reemplazar todas las constantes aditivas en el tiempo de ejecución con una constante 1.
2. Mantener solo el término de orden más alto
3. Eliminar la constante de orden más alto

Primero veamos un ejemplo

for(i=1; i<=n; ++i)
{
    
    
   j = i;
   j++;
}

A través de la "notación O grande", la complejidad temporal de este código es: O (n), ¿por qué?

En la notación O grande, la fórmula de la complejidad del tiempo es: T (n) = O (f (n)), donde f (n) representa la suma del número de ejecuciones de cada línea de código y O representa el proporcional relación, esta fórmula El nombre completo de es: la complejidad de tiempo progresivo del algoritmo.

Sigamos mirando el ejemplo anterior, asumiendo que el tiempo de ejecución de cada línea de código es el mismo, usamos 1 tiempo de partícula para representar, luego la primera línea de este ejemplo toma 1 tiempo de partícula y la tercera línea de tiempo de ejecución es n tiempo de partícula, el tiempo de ejecución de la cuarta línea también es n tiempo de partícula (la segunda y la quinta líneas son símbolos, temporalmente ignorados), entonces el tiempo total es 1 tiempo de partícula + n tiempo de partícula + n tiempo de partícula, es decir ( 1 + 2n) Tiempo de partícula, es decir: T (n) = (1 + 2n) * tiempo de partícula. De este resultado, podemos ver que el consumo de tiempo de este algoritmo cambia con el cambio de n. Por lo tanto, podemos simplificar this La complejidad del tiempo del algoritmo se expresa como: T (n) = O (n)
¿Por qué podemos simplificar de esta manera, porque la notación O grande no se usa para representar verdaderamente el tiempo de ejecución del algoritmo, se usa para representar ejecución de código La tendencia del crecimiento del tiempo.
Entonces, en el ejemplo anterior, si n es infinito, la constante 1 en T (n) = tiempo (1 + 2n) no tiene sentido y el múltiplo de 2 no tiene sentido. Por lo tanto, se puede simplificar directamente como T (n) = O (n).

Las medidas de complejidad de tiempo comunes son:
1. Orden constante O (1)
2. Orden logarítmico O (logN)
3. Orden lineal O (n)
4. Orden logarítmico lineal O (nlogN)
5. Orden cuadrado O (n²))
6. Orden cúbico O (n³)
7. K-ésimo orden O (n ^ k) [n elevado a la k-ésima potencia, el símbolo no será golpeado]
8. Orden exponencial (2 ^ n)
comparación de complejidad de tiempo común
O (1 ) <O (logn) <O (n) <O (nlogn) <O (n²) <O (n³) <O (2ⁿ) <O (n!)

Éstos son algunos de los más utilizados para explicar (no estrictamente de acuerdo con el orden):
Orden constante O (1):
no importa cuántas líneas de código se ejecuten, siempre que no haya una estructura compleja como bucles, el tiempo La complejidad de este código es O (1), como:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

Cuando se ejecuta el código anterior, su consumo no aumenta con el crecimiento de una determinada variable, por lo que no importa qué tan largo sea este tipo de código, incluso si hay decenas de miles de cientos de miles de líneas, se puede representar por O (1) Complejidad temporal.

Orden lineal O (n):
esto se explicó en el primer ejemplo de código, como:

for(i=1; i<=n; ++i)
{
    
    
   j = i;
   j++;
}

En este código, el código del bucle for se ejecutará n veces, por lo que el tiempo que consume varía con el cambio de n, por lo que este tipo de código puede usar O (n) para expresar su complejidad de tiempo.

Orden logarítmico O (logN):
primero veamos el código:

int i = 1;
while(i<n)
{
    
    
    i = i * 2;
}

Como puede ver en el código anterior, en el ciclo while, i se multiplica cada vez por 2. Después de la multiplicación, i se acerca cada vez más a n. Intentemos resolverlo. Suponiendo que después del ciclo x veces, i es mayor que 2, entonces el ciclo sale, es decir, la potencia x de 2 es igual an, entonces x = log2n [aquí es log 2 a la potencia n, el símbolo no será golpeado] En
otras palabras, cuando el bucle log2n [aquí es log 2 elevado a n, el símbolo no será golpeado] veces, el código terminará. Por lo tanto, la complejidad de tiempo de este código es: O (logn)

Orden logarítmico lineal O (nlogN):
El orden logarítmico lineal O (nlogN) es realmente muy fácil de entender. Si el código con complejidad de tiempo O (logn) se repite N veces, entonces su complejidad de tiempo es n * O (logN), que es O (nlogN).

Tome el código anterior con una pequeña modificación como ejemplo:

for(m=1; m<n; m++)
{
    
    
    i = 1;
    while(i<n)
    {
    
    
        i = i * 2;
    }
}

Orden cuadrado O (n²): El
orden cuadrado O (n²) es más fácil de entender. Si el código O (n) está anidado y en bucle de nuevo, su complejidad de tiempo será O (n²).
Por ejemplo:

for(x=1; i<=n; x++)
{
    
    
   for(i=1; i<=n; i++)
    {
    
    
       j = i;
       j++;
    }
}

Este código en realidad anida 2 niveles de n bucles, y su complejidad de tiempo es O (n * n), es decir, O (n²)
Si cambia el n de un nivel de bucle a m, es decir:

for(x=1; i<=m; x++)
{
    
    
   for(i=1; i<=n; i++)
    {
    
    
       j = i;
       j++;
    }
}

Entonces su complejidad temporal se convierte en O (m * n)

Orden cúbico O (n³), K-ésimo orden O (n ^ k):
Consulte O (n²) arriba para comprender, O (n³) es equivalente a tres capas de n ciclos, y las otras son similares.

Además, existen métodos de análisis de complejidad de tiempo promedio, complejidad de tiempo amortizado, complejidad de tiempo peor y mejor complejidad de tiempo, que son un poco complicados y no se ampliarán aquí.

2. Complejidad espacial

Dado que la complejidad del tiempo no se usa para calcular el tiempo específico que consume el programa, entonces también debo entender que la complejidad del espacio no se usa para calcular el espacio real ocupado por el programa.

La complejidad del espacio es una medida de la cantidad de espacio de almacenamiento que ocupa temporalmente un algoritmo durante su funcionamiento, también refleja una tendencia, y usamos S (n) para definirla.

La complejidad del espacio se usa comúnmente: O (1), O (n), O (n²), echemos un vistazo a continuación:

Complejidad espacial O (1)

Si el espacio temporal requerido para la ejecución del algoritmo no cambia con el tamaño de una determinada variable n, es decir, la complejidad espacial del algoritmo es una constante, que se puede expresar como O (1)
Ejemplo:

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

El espacio asignado por i, jym en el código no cambia con la cantidad de datos procesados, por lo que su complejidad espacial S (n) = O (1)

Complejidad espacial O (n)

Primero miramos un código:

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
    
    
   j = i;
   j++;
}

En este código, la primera línea del código es una nueva matriz. El tamaño de estos datos es n. En las líneas 2-6 de este código, aunque hay un bucle, no se asigna ningún espacio nuevo. Por lo tanto, el espacio de este código La complejidad depende principalmente de la primera línea, es decir, S (n) = O (n)
————————————————
Declaración de copyright: Este artículo es el original "Más que pensar "del blogger de CSDN El artículo cumple con el acuerdo de derechos de autor CC 4.0 BY-SA. Adjunte el enlace de la fuente original y esta declaración para reimprimir.
Enlace original: https://blog.csdn.net/jsjwk/article/details/84315770

Supongo que te gusta

Origin blog.csdn.net/weixin_43864187/article/details/103983179
Recomendado
Clasificación