【Estructura de datos】Primero comprenda la complejidad de tiempo y espacio de la estructura de datos.

El camino es largo y largo, y buscaré arriba y abajo. -- Qu yuan

 

Tabla de contenido

1. ¿Qué es una estructura de datos?

2. ¿Qué es un algoritmo?

1. La complejidad del algoritmo

2. Complejidad del tiempo

3. Ejercicios de complejidad temporal

4. Complejidad espacial


1. ¿Qué es una estructura de datos?

Una estructura de datos es una recopilación y manipulación de elementos de datos que tienen una o más relaciones específicas entre sí.

Se refiere a las interrelaciones entre los elementos de datos, es decir, la organización de los datos. Esta forma organizativa es la estructura lógica de los datos.

La lógica de los datos suele tener las siguientes cuatro estructuras básicas:

1. Instituciones colectivas

2. Estructura lineal

3. Estructura de árbol

4. Estructura del gráfico

En el proceso de procesamiento de datos por la computadora, debemos considerar cómo deben almacenarse los datos para que puedan reflejar la relación entre los datos.

La forma en que se almacenan los datos en la computadora es la estructura de almacenamiento de los datos . Por ejemplo, la lista secuencial, la lista enlazada, etc. para aprender más adelante .

Además, en el proceso de procesamiento de datos también ocurrirán operaciones como la eliminación, inserción y búsqueda de datos , por lo que también debemos considerar la forma de procesamiento de datos, es decir, el algoritmo .

2. ¿Qué es un algoritmo?

Algoritmo (Algoritmo) se refiere a la descripción precisa y completa del esquema de resolución de problemas, que es una serie de instrucciones claras para resolver el problema. El algoritmo representa el mecanismo de estrategia para describir la resolución de problemas de manera sistemática. Es decir, se puede obtener la salida requerida en un tiempo limitado para una determinada entrada estándar .

Al igual que la clasificación de burbujas, encontrar un número, buscar duplicados, etc., todos son algoritmos.

Características del algoritmo:

Finitud: un algoritmo debe poder terminar después de ejecutar un número finito de pasos.

Exactitud: Cada paso del algoritmo debe tener una definición exacta.

Entradas: Un algoritmo tiene 0 o más entradas para describir la situación inicial del operando.

Elemento de salida: un algoritmo tiene una o más salidas para reflejar el resultado del procesamiento de los datos de entrada, y un algoritmo sin salida no tiene sentido.

Viabilidad: cualquier paso computacional realizado en un algoritmo se puede dividir en pasos operativos ejecutables básicos.

1. La complejidad del algoritmo

Una vez que el algoritmo se compila en un programa ejecutable, necesita consumir recursos de tiempo y recursos de espacio (memoria) cuando se ejecuta. Por lo tanto, para medir la calidad de un algoritmo, generalmente se mide desde dos dimensiones de tiempo y espacio, es decir, complejidad de tiempo y complejidad de espacio.

La complejidad del tiempo mide principalmente qué tan rápido se ejecuta un algoritmo, mientras que la complejidad del espacio mide principalmente el espacio adicional requerido para que se ejecute un algoritmo. En los primeros días del desarrollo de las computadoras, las computadoras tenían muy poca capacidad de almacenamiento . Así que estoy muy preocupado por la complejidad del espacio. Sin embargo, con el rápido desarrollo de la industria informática, la capacidad de almacenamiento de las computadoras ha alcanzado un nivel muy alto. Así que ya no necesitamos prestar especial atención a la complejidad espacial de un algoritmo.

2. Complejidad del tiempo

Definición de complejidad temporal: En informática, la complejidad temporal de un algoritmo es una función (función matemática) que describe cuantitativamente el tiempo de ejecución de ese algoritmo. Teóricamente hablando, el tiempo que tarda en ejecutarse un algoritmo no se puede calcular, solo se puede saber si pones tu programa en la máquina y lo ejecutas. Pero, ¿necesitamos probar cada algoritmo en una computadora?Sí, podemos probar todos los algoritmos en una computadora, pero esto es muy problemático, por lo que tenemos el método de análisis de la complejidad del tiempo. El tiempo empleado por un algoritmo es proporcional al número de ejecuciones de las sentencias que contiene , y el número de ejecuciones de las operaciones básicas del algoritmo es la complejidad temporal del algoritmo .

Resumen: el algoritmo no es la cantidad de tiempo de ejecución, porque cuando ejecuta el código, la velocidad del tiempo también está relacionada con la configuración de su computadora y la velocidad de la red en este momento. Así que solo encuentre el número de ejecuciones del algoritmo. Es decir, la expresión matemática entre una oración básica determinada y el tamaño del problema N es calcular la complejidad temporal del algoritmo.

Ejemplo: ¿Calcular cuántas veces se ha ejecutado la instrucción count++ en Fun1?


void Func1(int N)
{
	int count = 0;

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			count++;
		}
	}

	for (int k = 0; k < 2 * N; k++)
	{
		count++;
	}
	int M = 10;
	while (M--)
	{
		count++;
	}
	printf("%dn", count);
}

El número total de bucles anteriores: la expresión de la función matemática F(N)=N^2+2*N+10.

La complejidad del tiempo es F(N)=N^2+2*N+10.

Cuando N toma diferentes valores:

  • N = 10 F(N) = 130
  • N = 1000 F(N) = 1002010
  • N = 100000 F(N) = 10000200010

Aquí podemos ver que a medida que N aumenta gradualmente, 2*N+10 en F(N)=N^2+ 2*N+10 tiene cada vez menos influencia en el valor total de la función. La complejidad temporal se acerca cada vez más a N^2, podemos decir que N^2 es la complejidad temporal de este algoritmo.

Para la complejidad del tiempo, usamos la notación asintótica de 0 grande:
notación de 0 grande (Big 0 notation)  : es un símbolo matemático que se usa para describir el comportamiento asintótico de las funciones.

Derivación del método Big 0: 
1. Reemplace todas las constantes aditivas en tiempo de ejecución con una constante 1 . 2. En la función de tiempos de ejecución modificados, solo se mantiene el término de mayor orden . 3. Si existe el artículo de mayor orden y no es 1 , elimine la constante multiplicada por este artículo . El resultado obtenido es del orden de 0.

Después de usar la representación asintótica del gran 0, la complejidad temporal de Func1 es: O(N^2).

Por lo anterior, encontraremos que la representación progresiva del 0 grande elimina aquellos ítems que tienen poca influencia en el resultado, y expresa el número de ejecuciones de forma clara y concisa. Además, existen complejidades de tiempo en el mejor, promedio y peor de los casos de algunos algoritmos:


Peor caso: Número máximo de ejecuciones para cualquier tamaño de entrada (límite superior)
Caso promedio: Número esperado de ejecuciones para cualquier tamaño de entrada
Mejor caso: Número mínimo de ejecuciones para cualquier tamaño de entrada (límite inferior)


Por ejemplo: Buscando un dato x en una matriz de longitud N
Mejor caso: 1 hallazgo
Peor caso: N hallazgos
Promedio de casos: N/2 hallazgos
En la práctica, el caso general se enfoca en las peores condiciones operativas del algoritmo , por lo que el tiempo la complejidad de buscar datos en la matriz es 0(N) .

3. Ejercicios de complejidad temporal

1. ¿Cuál es la complejidad temporal de Func2?

void Fun2(int N)
{
	int count = 0;
	for (int k = 0; k < 2 * N; k++)
	{
		count++;
	}
	int M = 10;
	while (M--)
	{
		count++;
	}
	printf("%d\n", count);
}

F(N) exacta=2*N+10.

A medida que N continúa aumentando, el tamaño de F(N) no tiene nada que ver con 10, por lo que al expresar la complejidad del tiempo, se debe eliminar 10, y de acuerdo con el tercer punto en la derivación del método de orden 0 grande: 3. Si existe el término de mayor orden y no es 1 , se elimina la constante multiplicada por este término . El resultado obtenido es del orden de 0. Entonces 2 en 2*N también se puede quitar.

Por lo tanto, la complejidad temporal de Func2 es O(N).

2. ¿Cuál es la complejidad temporal de calcular Func3?

void Func3(int N, int M)
{
	int count = 0;
	for (int k = 0; k < M; k++)
	{
		count++;
	}
	for (int k = 0; k < N; k++)
	{
		count++;
	}
	printf("%d\n", count);
}

Obviamente, no existe una relación obvia entre M y N, por lo que la complejidad temporal es O(N+M).

1. Si N es mucho mayor que M, la complejidad temporal es O(N).

2. Si M es mucho mayor que N, la complejidad temporal es O(M).

3. Si M y N tienen aproximadamente el mismo tamaño, la complejidad temporal es O(N) u O(M).

3. ¿Calcular la complejidad temporal de strchr?

La función de la función strchr es encontrar un carácter específico en una cadena y, si se encuentra el carácter, devuelve la dirección donde aparece el primer carácter. Si no se encuentra el carácter después de buscar la cadena, se devuelve un puntero nulo.

#include<string.h>//NULL空指针需要的头文件
#include<assert.h>//assert必须要的头文件
char* strchr(const char* str, int character)
{ //字符的ASCll值就是数子,所以这里字符的数据类型可以用int
	assert(str);
	while (*str)
	{
		if (*str == character)
			return str;
		else
			str++;
	}
	return NULL;
 }

 Al calcular la complejidad del tiempo, todos calculamos en el peor de los casos , por lo que la complejidad del tiempo del algoritmo strchr es O(N).

3. ¿Calcular la complejidad temporal de la ordenación de burbujas?

void Bulllesort(int *arr,int N)
{
    assert(arr);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i; j++)
        {
            if (arr[j] > arr[j + 1]) {
                int ret = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = ret;
            }
        }
    }

 Aquí se puede ver que al ingresar a la clasificación de burbujas por primera vez, la matriz debe intercambiarse 9 veces, al ingresar a la clasificación de burbujas por segunda vez, la matriz debe intercambiarse 8 veces, y así sucesivamente. De hecho, esta es una secuencia aritmética. F(N)=N(1+N)/2, por lo que la complejidad del tiempo es O(N^2).

4. ¿Calcular la complejidad temporal de la búsqueda binaria?

int Binarysearch(int nums[], int size, int target) 
{
    int left = 0;
    int right = size - 1;	
    while (left <= right) {
        int middle = left + ((right - left) / 2);
        if (nums[middle] > target)
        {
            right = middle - 1;
        }
        else if (nums[middle] < target)
        {
            left = middle + 1;
        }
        else {
            return middle;
        }
        }
}

Calculamos la complejidad del tiempo en el peor de los casos En la búsqueda binaria, el peor de los casos es que el número buscado está exactamente en el medio. Eso es 2^x=N, x es el número de búsquedas. En matemáticas, log es un logaritmo con base 2, pero no es fácil de escribir en el teclado, por lo que se simplifica a log2, por lo que la complejidad temporal de la búsqueda binaria Eso es O(log2).

4. Complejidad espacial

La complejidad del espacio también es una expresión de función matemática, que es una medida del espacio de almacenamiento temporal ocupado por un algoritmo durante la operación.
La complejidad del espacio no es cuántos bytes ocupa el programa , porque esto no es muy significativo. Así que la complejidad del espacio cuenta el número de variables . Las reglas de cálculo de la complejidad del espacio son básicamente similares a la complejidad práctica, y también se utiliza la representación asintótica del 0 grande.
Nota: El espacio de pila (parámetros de almacenamiento, variables locales, alguna información de registro, etc.) requerido por la función en tiempo de ejecución se ha determinado durante la compilación, por lo que la complejidad del espacio está determinada principalmente por el espacio extra solicitado explícitamente por la función en tiempo de ejecución.
 

void Bulllesort(int *arr,int N)
{
    assert(arr);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i; j++)
        {
            if (arr[j] > arr[j + 1]) {
                int ret = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = ret;
            }
        }
    }

Al igual que este tipo de burbujas, además de los parámetros de la función, se definen dos variables adicionales i y j , por lo que la complejidad del espacio es O(1).

Hoy en día, la capacidad de espacio de las computadoras es relativamente grande y la complejidad del espacio no es muy importante.

Comparaciones comunes de complejidad:

 

 

No es fácil de crear, espero que todos puedan dar algunos me gusta, gracias. 

Supongo que te gusta

Origin blog.csdn.net/adcxhw/article/details/129509152
Recomendado
Clasificación