- 1 1. Panoramica della funzione qsort
- 2 2. Parametri e utilizzo di qsort
- 3 3. Come funziona internamente qsort: L’algoritmo Quicksort
- 4 4. Creazione di funzioni di confronto
- 5 5. Ordinamento di array di strutture con qsort
- 6 6. Ottimizzazione delle prestazioni e confronto con altri algoritmi
- 7 7. Conclusione
1. Panoramica della funzione qsort
La funzione qsort, fornita nella libreria standard di C, è uno strumento potente per ordinare gli elementi all’interno di un array. Utilizzando l’algoritmo quicksort, qsort può riorganizzare i dati in modo efficiente ad alta velocità. Questa sezione spiega le basi di qsort e discute perché questa funzione è essenziale per la programmazione in C.
Cos’è qsort?
qsort è una funzione versatile che ordina array o liste basandosi su una funzione di confronto definita dall’utente. Come funzione standard in C, è ampiamente utilizzata in vari ambienti di sviluppo. Ad esempio, è possibile ordinare in modo efficiente array di interi, array di stringhe e persino array di strutture.
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main() {
int values[] = {40, 10, 100, 90, 20, 25};
size_t values_len = sizeof(values)/sizeof(values[0]);
qsort(values, values_len, sizeof(int), compare);
for(int i = 0; i < values_len; i++) {
printf("%d ", values[i]);
}
return 0;
}
Il codice sopra dimostra un esempio base di ordinamento di un array di interi utilizzando qsort. Qui, una funzione di confronto determina l’ordine degli elementi all’interno dell’array.
2. Parametri e utilizzo di qsort
Il prototipo per qsort è il seguente:
void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));
Dettagli dei parametri
- base : Puntatore al primo elemento dell’array da ordinare.
- num : Numero di elementi nell’array.
- size : Dimensione di ciascun elemento in byte.
- compar : Puntatore alla funzione di confronto.
Questa funzione ordina gli elementi basandosi sulla funzione di confronto. compar prende due elementi come argomenti e restituisce quale sia maggiore. Questa flessibilità consente di ordinare vari tipi di dati.
Come creare una funzione di confronto
La funzione di confronto è la chiave di come funziona qsort. Si definisce una funzione che confronta due elementi, come mostrato di seguito:
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
Questa funzione confronta i valori di a e b. Restituisce un valore negativo se a è minore di b, 0 se uguali, o un valore positivo se maggiore. Questo permette a qsort di ordinare l’array in ordine crescente.
3. Come funziona internamente qsort: L’algoritmo Quicksort
qsort utilizza internamente l’algoritmo quicksort. Quicksort è un algoritmo divide-et-impera che funziona come segue:
- Seleziona un pivot : Scegli un elemento pivot, spesso dal mezzo o dalla fine dell’array.
- Partizione : Sposta gli elementi minori del pivot a sinistra e quelli maggiori a destra.
- Ordinamento ricorsivo : Ripeti ricorsivamente il processo per ciascun sotto-array.
Questo processo di divisione e combinazione permette di ordinare l’array in modo efficiente. La complessità temporale media di Quicksort è O(n log n), rendendolo molto più veloce di molti altri algoritmi di ordinamento. Tuttavia, nel caso peggiore (come array già ordinati), la complessità può degradare a O(n^2), quindi è necessaria attenzione.

4. Creazione di funzioni di confronto
Il potere di qsort risiede nella sua capacità di utilizzare funzioni di confronto personalizzate per diversi tipi di dati. Di seguito sono riportati esempi per diversi tipi di dati.
Funzione di confronto per interi
int compare_int(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
Funzione di confronto per stringhe
int compare_str(const void *a, const void *b) {
return strcmp(*(const char**)a, *(const char**)b);
}
Funzione di confronto per strutture
struct Person {
int id;
const char* name;
};
int compare_person(const void *a, const void *b) {
return ((struct Person*)a)->id - ((struct Person*)b)->id;
}
Con funzioni di confronto personalizzate come queste, qsort può ordinare in modo flessibile gli array basandosi sul loro contenuto.
5. Ordinamento di array di strutture con qsort
qsort è particolarmente utile per ordinare array che contengono strutture. Ad esempio, considera l’ordinamento di un array di strutture Person in base al campo id:
struct Person people[] = {
{1, "Alice"},
{3, "Charlie"},
{2, "Bob"}
};
qsort(people, 3, sizeof(struct Person), compare_person);
Utilizzando la funzione compare_person, è possibile ordinare per id e disporre l’ordine come Alice, Bob e Charlie.
6. Ottimizzazione delle prestazioni e confronto con altri algoritmi
Prestazioni di Quicksort
Quicksort è altamente efficiente quando si lavora con dati casuali, con una complessità temporale media di O(n log n). Tuttavia, per dati già ordinati, le sue prestazioni nel caso peggiore possono scendere a O(n^2). Pertanto, mentre quicksort è consigliato per set di dati casuali, altri algoritmi possono risultare migliori in condizioni specifiche.
Confronto con Heapsort
Heapsort offre prestazioni stabili a O(n log n) anche nel caso peggiore, rendendolo più coerente rispetto a quicksort. Tuttavia, quicksort è tipicamente più veloce in media con dati casuali, quindi rimane una scelta preferita nella maggior parte degli scenari.
Confronto con Mergesort
Mergesort è anche un algoritmo di ordinamento stabile con complessità O(n log n). È adatto quando è necessario un ordinamento stabile (mantenere l’ordine originale per gli elementi uguali). Sebbene quicksort non sia stabile, per la maggior parte delle applicazioni comuni questo non rappresenta un problema significativo.
7. Conclusione
qsort è una potente funzione di ordinamento disponibile in C, nota per la sua flessibilità e velocità. Utilizzando funzioni di confronto personalizzate, è possibile ordinare array di vari tipi di dati e strutture che rende qsort estremamente pratico per l’uso nel mondo reale.
Comprendere l’algoritmo quicksort ti consente di sfruttare al meglio qsort. A seconda del tuo set di dati e dei requisiti, considera il confronto con altri algoritmi come heapsort o mergesort per ottimizzare le prestazioni.
Prova ad applicare qsort in modo appropriato nei tuoi futuri progetti di sviluppo per scrivere programmi C più efficienti.



