46 lines
936 B
C
46 lines
936 B
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef int comp_func(void const *left, void const *right);
|
|
|
|
static int partition(void *base, size_t size, comp_func *compare,
|
|
int low, int high)
|
|
{
|
|
#define AT(n) (base + size * (n))
|
|
|
|
__attribute__((aligned(4))) char tmp[size], pivot[size];
|
|
memcpy(pivot, AT((low + high) >> 1), size);
|
|
|
|
int i = low - 1;
|
|
int j = high + 1;
|
|
|
|
while(1) {
|
|
do i++;
|
|
while(compare(AT(i), pivot) < 0);
|
|
|
|
do j--;
|
|
while(compare(AT(j), pivot) > 0);
|
|
|
|
if(i >= j) return j;
|
|
|
|
memcpy(tmp, AT(i), size);
|
|
memcpy(AT(i), AT(j), size);
|
|
memcpy(AT(j), tmp, size);
|
|
}
|
|
}
|
|
|
|
static void sort(void *base, size_t size, comp_func *compare,
|
|
int low, int high)
|
|
{
|
|
if(low >= high) return;
|
|
|
|
int p = partition(base, size, compare, low, high);
|
|
sort(base, size, compare, low, p);
|
|
sort(base, size, compare, p+1, high);
|
|
}
|
|
|
|
void qsort(void *base, size_t n, size_t size, comp_func *compare)
|
|
{
|
|
sort(base, size, compare, 0, n-1);
|
|
}
|