Explication détaillée de la fonction qsort (le soldat magique dans le monde du tri en langage C)

Peu importe à quel point la route est amère, tant que vous marchez dans la bonne direction, aussi difficile soit-elle, vous serez plus proche du bonheur que de rester immobile. 

Table des matières


  Bonjour à tous, je suis Ji Ning. 

  Cet article vous apportera une fonction très puissante qui pourra résoudre rapidement la plupart des problèmes de tri que vous rencontrez. Avant d'apprendre les structures de données et les algorithmes, cette fonction est le dieu du tri !

1. Explication détaillée et utilisation de la fonction qsort  

  Si vous n'avez pas appris la structure des données et utilisez uniquement le tri à bulles, vous devez alors apprendre la fonction de tri rapide qsort.

  La chose la plus confortable à propos de la fonction qsort pour les utilisateurs est qu'elle peut trier des données de n'importe quel type de données et que l'utilisateur n'a pas besoin d'écrire un algorithme pour réaliser le tri. La capture d'écran ci-dessous provient du site officiel de la fonction qsort. (site officiel de la fonction de tri rapide qsort : qsort )

  La fonction qsort a un total de 4 paramètres. Le premier paramètre base est la première adresse de la collection à trier ; le deuxième paramètre num est le nombre total d'éléments des données à trier ; le troisième paramètre size est chaque élément de la collection à trier La taille de l'espace mémoire occupé ; le quatrième paramètre est un pointeur de fonction (int(*)(const void*, const void*)) . Le quatrième paramètre doit être implémenté par l'utilisateur, mais il est également très simple : il suffit de déterminer le type de données des éléments à comparer, puis d'utiliser la méthode appropriée pour comparer la taille des données afin de renvoyer un entier signé.

  Parce que le type de retour du pointeur de fonction dans qsort est int et que les deux paramètres sont const void* ; deuxièmement, la fonction comper est de réaliser la comparaison de deux types de données, la fonction peut donc être conçue de la manière suivante

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

  Utilisez p1 et p2 pour accepter, mais étant donné que p1 et p2 sont tous deux des pointeurs de type void* et que les pointeurs de type void* ne peuvent pas être déréférencés, donc lors des comparaisons, les types forcés de p1 et p2 doivent être convertis en correspondants. pointeurs des types de données, puis déréférencez-les pour comparaison. Voici quelques exemples de différents types de données

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);//结构体类型,成员为字符串
}

  Après avoir utilisé la fonction qsort dans le code, puis conçu une fonction de comparaison très simple, le compilateur triera automatiquement les données. Bien sûr, si vous souhaitez trier l'ensemble de données par ordre décroissant, il vous suffit d'échanger les positions de p2 et p1 dans la fonction Comper Ça y est, avez-vous hâte d'essayer, n'est-ce pas plus simple que d'écrire des dizaines de lignes de code à trier ?

Deuxièmement, réalisez la fonction qsort

  Nous sommes les premiers à contacter, et le plus utilisé est l'algorithme de tri à bulles , puis nous utilisons le tri à bulles pour implémenter une fonction qsort identique, mais il peut être légèrement insuffisant en complexité temporelle. , haha, je comprends tout.

  Utilisez l'algorithme de tri des bulles pour réaliser la fonction qsort. L'idée du tri des bulles est que les petits nombres bouillonnent et les grands nombres se stabilisent. Mais en fait, l'un des plus gros problèmes est de savoir comment réaliser la comparaison et l'échange de différents types de données dans la partie comparaison du tri à bulles. Pour cela, nous pouvons profiter du fait que le paramètre passé par celui-ci est un pointeur nul. : forcer le pointeur nul Le type est converti en pointeur du type de données des données à comparer, et le pointeur converti est d'abord déréférencé pour comparer la taille, puis le contenu est échangé octet par octet (il suffit d'ajouter une boucle dans la partie échange du tri à bulles).

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;
}

  Une fois la partie comparaison et échange implémentée, la fonction my_qsort peut être utilisée comme fonction qsort. 

insérer la description de l'image ici

  Le blogueur écrit depuis longtemps, si vous pouvez offrir au blogueur un triple combo gratuit pour encourager le blogueur, alors je pense que votre pantalon thaïlandais est vraiment épicé ! ! !

Je suppose que tu aimes

Origine blog.csdn.net/zyb___/article/details/131837696
conseillé
Classement