Existe-t-il une fonction de bibliothèque disponible dans la bibliothèque standard C pour effectuer le tri?
Existe-t-il une fonction de bibliothèque disponible dans la bibliothèque standard C pour effectuer le tri?
Réponses:
qsort()
est la fonction que vous recherchez. Vous l'appelez avec un pointeur vers votre tableau de données, le nombre d'éléments dans ce tableau, la taille de chaque élément et une fonction de comparaison.
Il fait sa magie et votre tableau est trié sur place. Un exemple suit:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * elem1, const void * elem2)
{
int f = *((int*)elem1);
int s = *((int*)elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
int main(int argc, char* argv[])
{
int x[] = {4,5,2,3,1,0,9,8,6,7};
qsort (x, sizeof(x)/sizeof(*x), sizeof(*x), comp);
for (int i = 0 ; i < 10 ; i++)
printf ("%d ", x[i]);
return 0;
}
return (f > s) - (f < s);
qsort
fonction" Point 4 "Si deux éléments se comparent comme égaux, leur ordre dans le tableau trié résultant n'est pas spécifié."
La bibliothèque standard C / C ++ <stdlib.h>
contient une qsort
fonction.
Ce n'est pas la meilleure implémentation de tri rapide au monde mais elle est assez rapide et TRÈS FACILE à utiliser ... la syntaxe formelle de qsort est:
qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);
La seule chose que vous devez implémenter est la fonction compare_function, qui prend deux arguments de type "const void", qui peuvent être convertis en une structure de données appropriée, puis renvoyer l'une de ces trois valeurs:
1. Comparaison d'une liste d'entiers :
simplement coulé a et b des nombres entiers de cas x < y
, x-y
est négative, x == y
, x-y = 0
, x > y
, x-y
est positif
x-y
est un moyen de raccourci pour le faire :) inverse *x - *y
à *y - *x
de tri décroissant / ordre inverse
int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}
2. Comparaison d'une liste de chaînes :
Pour comparer une chaîne, vous avez besoin d'une strcmp
fonction dans <string.h>
lib.
strcmp
retournera par défaut -ve, 0, ve de manière appropriée ... pour trier dans l'ordre inverse, inversez simplement le signe renvoyé par strcmp
#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}
3. Comparaison des nombres à virgule flottante :
int compare_function(const void *a,const void *b) {
double *x = (double *) a;
double *y = (double *) b;
// return *x - *y; // this is WRONG...
if (*x < *y) return -1;
else if (*x > *y) return 1; return 0;
}
4. Comparaison des enregistrements en fonction d'une clé :
Parfois, vous devez trier des éléments plus complexes, tels que des enregistrements. Voici le moyen le plus simple de le faire à l'aide de la qsort
bibliothèque.
typedef struct {
int key;
double value;
} the_record;
int compare_function(const void *a,const void *b) {
the_record *x = (the_record *) a;
the_record *y = (the_record *) b;
return x->key - y->key;
}
int
, les valeurs transmises au comparateur sont toutes deux int *
déguisées en void *
. Lors du tri d'un tableau de char *
, par conséquent, les valeurs transmises au comparateur sont toutes deux char **
déguisées en void *
. Par conséquent, le bon code doit être: int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }
.
if (x > y) return +1; else if (x < y) return -1; else return 0;
, ou si vous voulez une expression simple, alors return (x > y) - (x < y);
. Cela évalue toujours deux comparaisons au niveau C, mais l'optimiseur pourrait peut-être éviter cela. La soustraction ne fonctionne pas sur les valeurs non signées. La première version fonctionne bien lorsque vous avez affaire à une série de comparaison - en comparant d'abord 2 membres entiers d'une structure, et s'ils sont égaux, alors deux doubles, puis deux chaînes, etc. Il y a plus d'une façon de le faire, en C ainsi qu'en Perl.
Bien sûr: qsort()
est une implémentation d'une sorte (pas nécessairement de tri rapide comme son nom pourrait le suggérer).
Essayez man 3 qsort ou lisez-le sur http://linux.die.net/man/3/qsort
qsort
ne doit pas être implémenté à l'aide de Quicksort.
Bien que n'étant pas exactement dans la bibliothèque standard, https://github.com/swenson/sort ne contient que deux fichiers d'en-tête que vous pouvez inclure pour accéder à un large éventail de routages de tri incroyablement rapides, comme ceci:
#define SORT_NAME int64 #define SORT_TYPE int64_t #define SORT_CMP ( x , y ) (( x ) - ( y )) #include "sort.h" / * Vous avez maintenant accès à int64_quick_sort, int64_tim_sort, etc., par exemple * / int64_quick_sort ( arr , 128 ); / * Suppose que vous avez des int * arr ou int arr [128]; * /
Cela devrait être au moins deux fois plus rapide que la bibliothèque standard qsort
, car elle n'utilise pas de pointeurs de fonction et propose de nombreuses autres options d'algorithme de tri.
Il est en C89, il devrait donc fonctionner dans pratiquement tous les compilateurs C.
essayez qsort
dans stdlib.h.
Utiliser qsort()
dans <stdlib.h>
.
@paxdiablo La qsort()
fonction est conforme à la norme ISO / CEI 9899: 1990 (`` ISO C90 '').
Plusieurs fonctions de tri C sont disponibles dans stdlib.h
. Vous pouvez faire man 3 qsort
sur une machine unix pour en obtenir une liste, mais ils incluent: