Algoritmo de clasificación ----- clasificación por conteo

Tabla de contenido

Prefacio:

contando ordenar

1.Descripción del algoritmo

2. Idea básica

 3. Implementar lógica

4.Análisis de ejemplo

5. Demostración de animación.

Código

1.Código C/C++

2.Código Python

Análisis de algoritmos

complejidad del tiempo 

complejidad espacial

estabilidad

limitación 


Prefacio:

        ¿Existe un algoritmo de clasificación cuya complejidad temporal sea linealmente proporcional? Por supuesto que sí, es decir, contando, entonces, ¿por qué el algoritmo de clasificación tiene una complejidad de tiempo tan pequeña, pero su velocidad de clasificación no es tan buena como la clasificación rápida (nlogn)? Aquí pensaremos que puede haber otro precio a pagar. Sí, ese es el precio a pagar por los recursos espaciales. ¡Echemos un vistazo juntos!

contando ordenar

1.Descripción del algoritmo

La clasificación por conteo es un algoritmo de clasificación         no basado en comparación propuesto por Harold H. Seward en 1954. Su ventaja es que al ordenar números enteros dentro de un cierto rango, su complejidad es Ο (n + k) (donde k es el rango de números enteros), que es más rápido que cualquier algoritmo de clasificación por comparación. [1] Por supuesto, esta es una forma de sacrificar espacio por tiempo, y cuando O (k)> O (n * log (n)), su eficiencia no es tan buena como la clasificación basada en comparación ( la complejidad temporal   de la comparación La clasificación basada en es El límite inferior teórico es O (n * log (n)), como la clasificación por combinación y la clasificación por montón )

2. Idea básica

La ordenación por conteo utiliza una matriz C adicional, donde el i-ésimo elemento es el número de elementos cuyo valor es igual a i en la matriz A que se va a ordenar.

El núcleo de la clasificación por conteo es convertir los valores de los datos de entrada en claves y almacenarlos en el espacio de matriz abierto adicionalmente. Como ordenación de complejidad de tiempo lineal, la ordenación por conteo requiere que los datos de entrada sean números enteros dentro de un cierto rango.

La longitud de la matriz C utilizada para contar depende del rango de los datos en la matriz que se va a ordenar (igual a la diferencia entre el valor máximo y el valor mínimo de la matriz que se va a ordenar más 1), y luego se asigna y recopila :

①Distribución._  _ _ Escanee la matriz original una vez, use el valor actual -minValue como subíndice y aumente el contador del subíndice en 1.
②Recoger._  _ _ Escanee la matriz de contadores y recopile los valores en orden.

 3. Implementar lógica

① Encuentre los elementos más grandes y más pequeños en la matriz a
ordenar ② Cuente el número de apariciones de cada elemento con valor i en la matriz y guárdelo en el i-ésimo elemento de la matriz C
③ Acumule todos los recuentos (desde el primero en C A partir del elemento, cada elemento se agrega al elemento anterior)
④ Complete la matriz de destino a la inversa: coloque cada elemento i en el elemento C (i) de la nueva matriz y reste 1 de C (i) para cada elemento colocado.

4.Análisis de ejemplo

Supongamos que hay una matriz [2,1,5,1,3,8,4,5,6,10,7] ¿ Cómo implementar la clasificación mediante clasificación por conteo?

El primer paso es encontrar el elemento máximo máximo de esta matriz, que es 10, y luego crear una matriz count[max+1], es decir, count[11], e inicializar todos los números en count a 0, como se muestra abajo:

contar [0,0,0,0,0,0,0,0,0,0,0]

En el segundo paso , comience a recorrer la matriz original, luego cuente el número de elementos que contiene y realice una operación +1 en la matriz de conteo en la posición correspondiente. Por ejemplo, si 1 aparece dos veces en la matriz original, agregue 2 al recuento [0], es decir, recuento [0] = 2. Count cuenta el número de apariciones de los elementos de la matriz original en secuencia. Las estadísticas son las siguientes:

                 1 2 3 4 5 6 7 8 9 10        

contar 2 1 1 1 2 1 1 0 0 1 (este es el número de ocurrencias contadas)

El tercer paso es completar y cubrir la matriz original en orden y finalmente obtener la matriz ordenada.

1 1 2 3 4 5 5 6 7 10

5. Demostración de animación.

Código

1.Código C/C++

#include<stdio.h>
#include<string.h>
//获取最大值
int get_max(int* n,int length) {
	int max = n[0];
	for (int i = 1; i < length; i++) {
		if (n[i]>max)
			max = n[i];
	}
	return max;
}

//计数排序
void count_sort(int* n, int max, int length) {
	int index=0;
	int range =max+1;
	int* temp_arr = (int*)malloc(sizeof(int) * range);
	memset(temp_arr, 0, sizeof(int) * range); //初始化全部都为0
	for (int j = 0; j < length; j++) { //统计
		temp_arr[n[j]]++;
	}
	
	for (int k = 0; k < range; k++) {
		while (temp_arr[k]) {
			n[index++]=k;//把统计后的数字覆盖给原数组上
			temp_arr[k]--;
		}
	}
	free(temp_arr);//释放空间
}
int main() {
	int array[11] = { 2,1,5,1,3,8,4,5,6,10,7 };
	printf("排序前:");
	for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
		printf("%d ", array[i]);
	}
	printf("\n排序后:");
	count_sort(array, get_max(array, sizeof(array) / sizeof(int)),sizeof(array) / sizeof(int));
	for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
		printf("%d ", array[i]);
	}
}
//排序前:2 1 5 1 3 8 4 5 6 10 7
//排序后:1 1 2 3 4 5 5 6 7 8 10

2.Código Python

import random as r
def count_sort(li,max):
    length=len(li)  #获取长度
    index=0
    new_li=[0 for _ in range(max)] #进入到统计
    for i in li:
        new_li[i-1]+=1
    for j in range(0,len(new_li)): #覆盖原数组
        while new_li[j]:
            li[index]=j+1
            index+=1
            new_li[j]-=1
    return li           

if __name__ == '__main__':
    li=[r.randint(1,10) for _ in range(10)]
    print(li)
    sort_li=count_sort(li,max(li))
    print(sort_li)
    
# [3, 6, 6, 7, 7, 1, 9, 10, 8, 5]
# [1, 3, 5, 6, 6, 7, 7, 8, 9, 10]

Análisis de algoritmos

complejidad del tiempo 

O(n+k) 

complejidad espacial

De acuerdo)

estabilidad

 Estabilizar

limitación 

 Nota: La clasificación de conteo requiere abrir un espacio de memoria para almacenar estadísticas. Si la matriz a ordenar es muy grande, el espacio que se debe solicitar será muy grande. Esto es una pérdida de espacio, así que tenga cuidado al elegir .

Eso es todo por hoy, ¡hasta la próxima!

Comparte un fondo de pantalla: 

Supongo que te gusta

Origin blog.csdn.net/m0_73633088/article/details/132942106
Recomendado
Clasificación