logo

qsort() en C

qsort() est une fonction standard prédéfinie dans la bibliothèque C. Nous pouvons utiliser cette fonction pour trier un tableau par ordre croissant ou décroissant. Il utilise en interne l'algorithme de tri rapide, d'où le nom qsort. Il peut trier un tableau de n'importe quel type de données, y compris des chaînes et des structures. Cela fonctionne bien et est efficace à mettre en œuvre. Il existe une fonction sort() en C++ similaire à qsort() en C. Dans des aspects tels que le temps d'exécution, la sécurité et la flexibilité, sort() surpasse qsort().

Ce tutoriel explique la fonction qsort() avec des exemples. Le standard C n'a pas spécifié la complexité de la fonction, mais comme elle suit en interne l'algorithme de tri rapide, sa complexité temporelle moyenne est provisoirement considérée comme étant O(n*logn). La fonction est définie dans le fichier d'en-tête stdlib ; nous devons donc l'inclure avant de l'utiliser.

 #include 

Syntaxe de la fonction :

 qsort(array, number, size, function) 

tableau : Le tableau à trier.

nombre : Nombre d'éléments dans le tableau que nous voulons trier

taille : Taille d'un élément individuel du tableau

fonction : Fonction de comparaison personnalisée que nous devons écrire dans un format spécifié :

Format spécifié de la fonction :

 int compare( const void* a, const void* b) { } 
  • qsort() appelle la fonction compare() tous les deux éléments du tableau.
  • Les arguments a et b sont deux pointeurs vides pointant vers les deux éléments à comparer.
  • nous devons écrire le corps de compare() de la manière dont il doit renvoyer :
    1. 0 si deux éléments sont égaux
    2. -1 ou tout autre entier négatif si le premier élément est inférieur au deuxième élément
    3. 1 ou tout autre nombre positif si le premier élément est supérieur au second.
  • Le nom de la fonction de comparaison peut être n'importe quoi, mais le nom doit être exactement donné en argument à la fonction qsort().
  • const void* a signifie que a est un pointeur vide dont la valeur est fixe. Avant de l'utiliser, nous devons transtyper un pointeur vide vers un type de données.

Nous allons maintenant explorer les fonctions permettant de trier des tableaux de différents types de données.

1. Tri des entiers :

 #include #include int compare(const void* num1, const void* num2) // comparing function { int a = *(int*) num1; int b = *(int*) num2; if(a &gt; b) { return 1; } else if(a <b) { return -1; } 0; int main() arr[50], n, i; printf('enter the size of array to be sorted: '); scanf('%d', &n); printf('
enter elements into array: for(i="0;" i < n; i++) &arr[i]); qsort(arr, sizeof(int), compare); printf('
the sorted printf('
['); if(i="=" n-1) prevent a comma(,) after last element printf('%d', arr[i]); break; printf('%d, ', printf(']'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: 98 34 89 0 2 The sorted array: [0, 2, 34, 89, 98] </pre> <h3>Understanding:</h3> <p>In these two lines:</p> <p> <strong>int a = *(int*) num1;</strong> </p> <p> <strong>int b = *(int*) num2;</strong> </p> <p>The input array is of type . Hence, we must typecast the void pointers into integer pointers before performing any operations to allocate the required memory. We stored the values the two pointers are pointing at in two other integer variables, a and b. Then, we compared both values using the comparison operators.</p> <p>Instead of using two more temporary variables, we can write a one-line code:</p> <pre> int compare(const void* num1, const void* num2) { return *(int*)a - *(int*)b; } </pre> <ul> <li>If a==b, 0 is returned; if a &gt; b, a positive integer is returned; if a <b, a negative integer is returned.< li> </b,></li></ul> <h3>2. Sorting strings</h3> <pre> #include #include #include int compare(const void* num1, const void* num2) { //char **a = (char**)num1; //char **b = (char**)num2; //return strcmp(*a, *b); return strcmp(*(char**)num1, *(char**)num2); } int main() { int n, i; char* arr[50]; printf(&apos;Enter the size of the array to be sorted: &apos;); scanf(&apos;%d&apos;, &amp;n); printf(&apos;
Enter elements into the array: &apos;); for(i = 0; i <n; i++) { arr[i]="malloc(100*" sizeof(char)); scanf('%s', arr[i]); } qsort(arr, n, sizeof(char*), compare); printf('
the sorted array: '); printf('
['); for(i="0;" i < n; if(i="=" n-1) printf('%s', break; printf('%s, ', printf(']'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: hi hello how are you The sorted array: [are, hello, hi, how, you] </pre> <h3>Understanding:</h3> <ul> <li>We have an array of strings. The difference between an integer array and a string array is that: <ol class="points"> <li>An integer array is a collection of integers</li> <li>A string array is a collection of character arrays/character pointers.</li> </ol></li> <li>Hence, in the compare function, we need to typecast the void pointers to (char**)a and not (char*)a. <br> <strong>[[string 1], [string 2]?]</strong> <br> When we use char*, it points to the array, and then, to point to a string in the array, we need a double pointer.</li> <li>We used the strcmp() function here. The function is defined in the string.h header file. We need to include it first.</li> <tr><td>The function returns</td> : <ol class="points"> <li>0 if both strings are the same</li> <li>1 if the ASCII value of a character in the string is greater than the corresponding character in the second string</li> <li>-1 if the ASCII value of a character in the string is less than the corresponding character in the second string.</li> </ol> </tr></ul> <h3>3. Sorting an Array of Structure</h3> <pre> #include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -&gt; num1)- (b -&gt; num1); int second = (a -&gt; num2)- (b -&gt; num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf(&apos;Original array: 
&apos;); printf(&apos;[[&apos;); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf('%d, %d]]', array[i].num1, array[i].num2); break; } %d], [', qsort(array, 5, sizeof(s), compare); printf('
sorted array: 
'); printf('[['); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;></pre></n;></pre></b)>

Compréhension:

Dans ces deux lignes :

int a = *(int*) num1;

int b = *(int*) num2;

Le tableau d'entrée est de type . Par conséquent, nous devons transtyper les pointeurs vides en pointeurs entiers avant d’effectuer toute opération pour allouer la mémoire requise. Nous avons stocké les valeurs vers lesquelles pointent les deux pointeurs dans deux autres variables entières, a et b. Ensuite, nous avons comparé les deux valeurs à l’aide des opérateurs de comparaison.

Au lieu d'utiliser deux variables temporaires supplémentaires, nous pouvons écrire un code sur une seule ligne :

 int compare(const void* num1, const void* num2) { return *(int*)a - *(int*)b; } 
  • Si a==b, 0 est renvoyé ; si a > b, un entier positif est renvoyé ; si un

2. Tri des chaînes

 #include #include #include int compare(const void* num1, const void* num2) { //char **a = (char**)num1; //char **b = (char**)num2; //return strcmp(*a, *b); return strcmp(*(char**)num1, *(char**)num2); } int main() { int n, i; char* arr[50]; printf(&apos;Enter the size of the array to be sorted: &apos;); scanf(&apos;%d&apos;, &amp;n); printf(&apos;
Enter elements into the array: &apos;); for(i = 0; i <n; i++) { arr[i]="malloc(100*" sizeof(char)); scanf(\'%s\', arr[i]); } qsort(arr, n, sizeof(char*), compare); printf(\'
the sorted array: \'); printf(\'
[\'); for(i="0;" i < n; if(i="=" n-1) printf(\'%s\', break; printf(\'%s, \', printf(\']\'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: hi hello how are you The sorted array: [are, hello, hi, how, you] </pre> <h3>Understanding:</h3> <ul> <li>We have an array of strings. The difference between an integer array and a string array is that: <ol class="points"> <li>An integer array is a collection of integers</li> <li>A string array is a collection of character arrays/character pointers.</li> </ol></li> <li>Hence, in the compare function, we need to typecast the void pointers to (char**)a and not (char*)a. <br> <strong>[[string 1], [string 2]?]</strong> <br> When we use char*, it points to the array, and then, to point to a string in the array, we need a double pointer.</li> <li>We used the strcmp() function here. The function is defined in the string.h header file. We need to include it first.</li> <tr><td>The function returns</td> : <ol class="points"> <li>0 if both strings are the same</li> <li>1 if the ASCII value of a character in the string is greater than the corresponding character in the second string</li> <li>-1 if the ASCII value of a character in the string is less than the corresponding character in the second string.</li> </ol> </tr></ul> <h3>3. Sorting an Array of Structure</h3> <pre> #include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -&gt; num1)- (b -&gt; num1); int second = (a -&gt; num2)- (b -&gt; num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf(&apos;Original array: 
&apos;); printf(&apos;[[&apos;); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf(\'%d, %d]]\', array[i].num1, array[i].num2); break; } %d], [\', qsort(array, 5, sizeof(s), compare); printf(\'
sorted array: 
\'); printf(\'[[\'); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;></pre></n;>

Compréhension:

  • Nous avons un tableau de chaînes. La différence entre un tableau d'entiers et un tableau de chaînes est la suivante :
    1. Un tableau d'entiers est une collection d'entiers
    2. Un tableau de chaînes est une collection de tableaux de caractères/pointeurs de caractères.
  • Par conséquent, dans la fonction de comparaison, nous devons transtyper les pointeurs vides vers (char**)a et non (char*)a.
    [[chaîne 1], [chaîne 2] ?]
    Lorsque nous utilisons char*, il pointe vers le tableau, puis, pour pointer vers une chaîne du tableau, nous avons besoin d'un double pointeur.
  • Nous avons utilisé ici la fonction strcmp(). La fonction est définie dans le fichier d'en-tête string.h. Nous devons d’abord l’inclure.
  • La fonction renvoie:
    1. 0 si les deux chaînes sont identiques
    2. 1 si la valeur ASCII d'un caractère de la chaîne est supérieure au caractère correspondant dans la deuxième chaîne
    3. -1 si la valeur ASCII d'un caractère de la chaîne est inférieure au caractère correspondant dans la deuxième chaîne.

3. Tri d'un tableau de structures

 #include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -&gt; num1)- (b -&gt; num1); int second = (a -&gt; num2)- (b -&gt; num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf(&apos;Original array: 
&apos;); printf(&apos;[[&apos;); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf(\'%d, %d]]\', array[i].num1, array[i].num2); break; } %d], [\', qsort(array, 5, sizeof(s), compare); printf(\'
sorted array: 
\'); printf(\'[[\'); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;>

Compréhension:

Nous avons déclaré un tableau de type Structure, ce qui signifie que chaque élément du tableau est un tableau d'éléments de structure. Dans le programme ci-dessus, la structure comporte deux éléments entiers. La tâche consiste à trier le tableau par rapport au premier élément de la structure, et si deux premiers éléments sont égaux, nous devons le trier en utilisant le deuxième élément.

Exemple:

[[1, 2], [3, 4], [1, 4]]

Tableau trié : [[1, 2], [1, 4], [3, 4]]

Nous avons utilisé la fonction rand() pour générer des éléments aléatoires dans le tableau. Dans la fonction compare(), nous devons transtyper les deux pointeurs pour typer la structure.

qsort() en C

La spécialité de l'utilisation de qsort() est la fonction de comparaison personnalisée que nous pouvons concevoir comme nous le souhaitons. Nous pouvons également trier quelques éléments d’un tableau et laisser le reste non trié.