Explicación detallada de la función qsort (el soldado mágico en el mundo de clasificación en lenguaje C)

No importa cuán amargo sea el camino por delante, siempre que camines en la dirección correcta, no importa cuán difícil sea, estarás más cerca de la felicidad que de quedarte quieto. 

Tabla de contenido


  Hola a todos, soy Ji Ning. 

  Este artículo le brindará una función muy poderosa que puede resolver rápidamente la mayoría de los problemas de clasificación que encuentre. Antes de aprender estructuras de datos y algoritmos, ¡esta función es el dios de la clasificación!

1. Explicación detallada y uso de la función qsort  

  Si no ha aprendido la estructura de datos y solo usa la clasificación por burbujas, entonces debe aprender la función de clasificación rápida qsort.

  Lo más cómodo de la función qsort para los usuarios es que puede ordenar datos de cualquier tipo y no es necesario que el usuario escriba un algoritmo para lograr la clasificación. La siguiente captura de pantalla es del sitio web oficial de la función qsort. (Sitio web oficial de la función de clasificación rápida qsort: qsort )

  La función qsort tiene 4 parámetros en total, la base del primer parámetro es la primera dirección de la colección a ordenar; el número del segundo parámetro es el número total de elementos de los datos a ordenar; el tamaño del tercer parámetro es cada elemento del colección a ordenar El tamaño del espacio de memoria ocupado; el cuarto parámetro es un puntero de función (int(*)(const void*, const void*)) . El cuarto parámetro debe ser implementado por el usuario, pero también es muy simple: solo necesita determinar el tipo de datos de los elementos a comparar y luego usar el método apropiado para comparar el tamaño de los datos y devolver un entero con signo.

  Debido a que el tipo de retorno del puntero de función en qsort es int y ambos parámetros son constantes void *, en segundo lugar, la función de la función comper es realizar la comparación de dos tipos de datos, por lo que la función se puede diseñar de la siguiente manera

int Comper(const void* p1, const void* p2)
{
	;//需要将传进来的p1、p2进行比较 
}

  Use p1 y p2 para aceptar, pero considerando que tanto p1 como p2 son punteros de tipo void*, y los punteros de tipo void* no se pueden desreferenciar, por lo que al hacer comparaciones, los tipos forzados de p1 y p2 deben convertirse en los correspondientes. punteros de los tipos de datos y luego eliminar la referencia de ellos para compararlos. A continuación se muestran algunos ejemplos de diferentes tipos de datos

int Comper(const void* p1, const void* p2)
{
	return (*(int*)p1) - (*(int*)p2);//整型数据
}
int Comper(const void* p1, const void* p2)
{
	return strcmp((*(char*)p1), (*(char*)p2));//字符型数据
}
int Comper(const void* p1, const void* p2)
{
	return (*(float*)p1) - (*(float*)p2);//浮点型数据
}
int Cmpper(const void* p1, const void* p2)
{
	return (((struct Stu*)p1)->age - ((struct Stu*)p2)->age);//结构体类型,成员为整形
}
int Cmpper(const void* p1, const void* p2)
{
	return  strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);//结构体类型,成员为字符串
}

  Después de usar la función qsort en el código y luego diseñar una función de comparación muy simple, el compilador ordenará los datos automáticamente. Por supuesto, si desea ordenar el conjunto de datos en orden descendente, solo necesita intercambiar las posiciones de p2 y p1 en la función Comper Eso es todo, ¿estás ansioso por intentarlo? ¿No es más fácil que escribir docenas de líneas de código para ordenar?

En segundo lugar, realice la función qsort

  Somos los primeros en contactar, y el más utilizado es el algoritmo de clasificación de burbujas . Luego usamos la clasificación de burbujas para implementar una función qsort idéntica, pero puede ser un poco insuficiente en términos de complejidad temporal. Jaja, lo entiendo todo.

  Utilice el algoritmo de clasificación de burbujas para implementar la función qsort. La idea de la clasificación de burbujas es que los números pequeños burbujean y los grandes se asientan. Pero de hecho, uno de los mayores problemas es cómo lograr la comparación e intercambio de diferentes tipos de datos en la parte de comparación del tipo burbuja, para ello podemos aprovechar que el parámetro que pasa es un puntero nulo. : forzar el puntero nulo El tipo se convierte en un puntero del tipo de datos que se van a comparar, y primero se desreferencia el puntero convertido para comparar el tamaño, y luego el contenido se intercambia byte por byte (simplemente agregue un bucle en la parte de intercambio del tipo burbuja).

void my_qsort(void* base, size_t Num, size_t Size, int(*Com)(const void*, const void*))//首元素地址  元素个数  每个元素的字节数  Com比较函数
{
	int i = 0;
	for (i = 0; i < Num - 1; i++)//循环的趟数
	{
		int j = 0;
		for (j = 0; j < Num - 1 - i; j++)//每趟循环要比较的次数
		{
			//实现比较、交换
			if (Com((char*)base + Size * j, (char*)base + Size * (j + 1)) > 0)
			{
				//交换---逐个字节交换n   
				int z = 0;
				for (z = 0; z < Size; z++)
				{
					char tmp = 0;
					tmp = *((char*)base + Size * j + z);
					*((char*)base + Size * j + z) = *((char*)base + Size * (j + 1) + z);
					*((char*)base + Size * (j + 1) + z) = tmp;
				}
			}
		}
	}
}
int Comper(const void* p1, const void* p2)
{
	return (*((int*)p1) - *((int*)p2));
}
int main()
{
	//测试my_qsort函数
	int arr[10] = { 4,3,5,6,7,8,9,10,2,1 };
	my_qsort(arr, 10, 4, Comper);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

  Una vez implementada la parte de comparación e intercambio, la función my_qsort se puede utilizar como función qsort. 

inserte la descripción de la imagen aquí

  El blogger ha estado escribiendo durante mucho tiempo, si puedes darle al blogger un combo triple gratis para animarlo, ¡entonces creo que tus pantalones tailandeses son realmente picantes! ! !

Supongo que te gusta

Origin blog.csdn.net/zyb___/article/details/131837696
Recomendado
Clasificación