Qsort (jazyk C)
<ctype.h> | <limits.h> | <stdio.h> | <stdlib.h> | <math.h> | <string.h> | <time.h> |
---|---|---|---|---|---|---|
isalnum |
printf |
system |
Funkcia qsort
knižnica | stdlib.h |
popis | Funkcia implementuje algoritmus vyhľadávania Quick sort. |
Úplný funkčný prototyp:
void qsort(void *base, size_t nelem, size_t width, int (*fcmp)(const void *, const void *))
Podrobný popis funkcie
Funkcia vytriedi pole s použitím algoritmu Quick sort.
Parametre
- base
- ukazovateľ typu void ukazujúci na nultý element triedeného poľa
- nelem
- počet elementov v triedenom poli
- width
- veľkosť jedného elementu v bajtoch
- fcmp
- ukazovateľ na porovnávaciu funkciu, ktorá porovnáva dva elementy triedeného poľa
Porovnávacia funkcia fcmp vyžaduje dva argumenty - ukazovatele typu const void *. Označme tieto argumenty elem1 a elem2. Potom úplný funkčný prototyp porovnávacej funkcie bude:
int (*fcmp)(const void *elem1, const void *elem2);
Poznámka: Pri porovnávaní porovnávame obsahy argumentov elem1 a elem2, to znamená, že píšeme napr. *elem1 < *elem2 namiesto elem1 < elem2. Zápis elem1 < elem2 by totiž znamenal, že máme porovnať hodnotu elem1 a elem2 čo by znamenalo, že máme porovnať nejaké adresy uložené v premenných elem1 a elem2 (tieto premenné sú ukazovatele a teda pamätajú adresu, nie samotnú štruktúru). Porovnanie elem1 < elem2 by teda bolo syntakticky správne, ale nemalo by zmysel. Chceme predsa porovnávať zamestnancov a nie adresy pamäte kde sú títo zamestnanci uložení.
Návratová hodnota
Od funkcie fcmp sa vyžaduje aby vracala celé číslo v závislosti od výsledku porovnania argumentov elem1 a elem2 nasledovne:
- ak *elem1 < *elem2 potom fcmp vráti celé číslo < 0
- ak *elem1 == *elem2 potom fcmp vráti 0
- ak *elem1 > *elem2 potom fcmp vráti celé číslo > 0
Pri porovnávaní elementov elem1 a elem2 symbol < znamená, že elem1 je menší ako elem2 v tom zmysle, že v utriedenom poli sa elem1 nachádza pred elem2. Podobne pre symbol >. Ak sú porovnávané elementy z pohľadu triediaceho kritéria ekvivalenté (symbol ==) potom funkcia vráti nulu. Napríklad ak porovnávame dva reťazce a kritériom je abcedné usporiadanie, potom reťazec "Alexandra" je menší ako reťazec "Zora". Ak by sme však chceli triediť podľa dĺžky reťazca, potom reťazec "Alexandra" je väčší ako reťazec "Zora".
Triedenie poľa sa potom realizuje volaním funkcie qsort s patričnými parametrami.
Príklad
Použitie funkcie qsort ilustrujeme na nasledujúcom jednoduchom príklade:
#include <stdio.h>
#include <stdlib.h>
#define POCET_PRVKOV 6
int pole[POCET_PRVKOV] = { 45, 11, 100, 30, 20, 27 };
int Porovnaj_cele_cisla (const void * a, const void * b)
{
// Parameter "a" je ukazovateľ typu "const void *". Preto ho pred použitím musíme pretypovať na poiter na "int". Čiže: "(int *)a".
// Pretože zápis "(int *)a" predstavuje ukazovateľ a my chceme porovnávať celé číslo, ktoré je uložené tam kde tento ukazovateľ ukazuje
// musíme ďalej napísať: "*(int *)a". Týmto zápisom sa dostaneme k hodnote čísla na ktoré ukazuje predaný parameter "const void * a".
// Podobne pre parameter "b".
return ( *(int*)a - *(int*)b );
}
int main ()
{
int n;
// Vzostupné utriedenie poľa:
qsort (pole, POCET_PRVKOV, sizeof(int), Porovnaj_cele_cisla);
// Výpis na monitor:
for (n=0; n<POCET_PRVKOV; n++)
printf ("%d ",values[n]);
return 0;
}