qsort - qsort
qsort je standardní knihovní funkcí jazyka C, která implementuje polymorfní třídicí algoritmus pro pole libovolných objektů podle porovnávací funkce poskytované uživatelem. Je pojmenován podle algoritmu „quicker sort“ ( varianta quicksortu díky RS Scowen), který byl původně použit k jeho implementaci do knihovny Unix C, ačkoli standard C k implementaci quicksortu nevyžaduje.
Implementace funkce qsort dosahuje polymorfismu , schopnosti třídit různé druhy dat, tím, že ukazatel funkce přejde na třícestnou srovnávací funkci, stejně jako parametr, který určuje velikost jejích jednotlivých vstupních objektů. Standard C vyžaduje funkci porovnání k implementaci celkového pořadí položek ve vstupním poli.
Dějiny
Funkci qsort implementoval Lee McMahon v roce 1972. Ve verzi 3 Unix byla zavedena jako knihovní funkce, ale tehdy šlo o podprogram assembleru .
Verze AC se zhruba rozhraním standardní verze C byla zavedena ve verzi 6 Unix . Byl přepsán v roce 1983 pro BSD . Funkce byla standardizována v ANSI C (1989).
V roce 1991 zaměstnanci společnosti Bell Labs zjistili, že verze qsortu McMahon a BSD by u některých jednoduchých vstupů spotřebovala kvadratický čas . Tak Jon Bentley a Douglas McIlroy navrhovaný nový rychlejší a robustnější implementaci.
Příklad
Následující část kódu C ukazuje, jak třídit seznam celých čísel pomocí qsort.
#include <stdlib.h>
/* Comparison function. Receives two generic (void) pointers to the items under comparison. */
int compare_ints(const void *p, const void *q) {
int x = *(const int *)p;
int y = *(const int *)q;
/* Avoid return x - y, which can cause undefined behaviour
because of signed integer overflow. */
if (x < y)
return -1; // Return -1 if you want ascending, 1 if you want descending order.
else if (x > y)
return 1; // Return 1 if you want ascending, -1 if you want descending order.
return 0;
// All the logic is often alternatively written:
return (x > y) - (x < y);
}
/* Sort an array of n integers, pointed to by a. */
void sort_ints(int *a, size_t n) {
qsort(a, n, sizeof(*a), compare_ints);
}
Rozšíření
Protože porovnávací funkce originálu qsort
přijímá pouze dva ukazatele, předávání dalších parametrů (např. Vytváření srovnávací funkce, která porovnává rozdíl mezi dvěma hodnotami s jinou hodnotou) musí být provedeno pomocí globálních proměnných . Problém byl v systémech podobných Unixům BSD a GNU vyřešen zaváděcí qsort_r
funkcí, která umožňuje předat do srovnávací funkce další parametr. Tyto dvě verze qsort_r
mají různé pořadí argumentů. Příloha K C11 definuje v qsort_s
podstatě identické s GNU qsort_r
. MacOS a FreeBSD libcs také obsahují qsort_b
variantu, která používá bloky , analogické k uzávěrům , jako alternativní řešení stejného problému.