libc: Implement an actual quicksort for qsort...
This commit is contained in:
parent
a7db67dbb1
commit
7975697786
@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@ -7,19 +8,46 @@
|
||||
extern char * _argv_0;
|
||||
extern int __libc_debug;
|
||||
|
||||
void qsort(void * base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
|
||||
if (!nmemb) return;
|
||||
if (!size) return;
|
||||
for (size_t i = 0; i < nmemb-1; ++i) {
|
||||
for (size_t j = 0; j < nmemb-1; ++j) {
|
||||
void * left = (char *)base + size * j;
|
||||
void * right = (char *)base + size * (j + 1);
|
||||
if (compar(left,right) > 0) {
|
||||
char tmp[size];
|
||||
memcpy(tmp, right, size);
|
||||
memcpy(right, left, size);
|
||||
memcpy(left, tmp, size);
|
||||
struct SortableArray {
|
||||
void * data;
|
||||
size_t size;
|
||||
int (*func)(const void *, const void *);
|
||||
};
|
||||
|
||||
static ssize_t partition(struct SortableArray * array, ssize_t lo, ssize_t hi) {
|
||||
char pivot[array->size];
|
||||
memcpy(pivot, (char *)array->data + array->size * hi, array->size);
|
||||
ssize_t i = lo - 1;
|
||||
for (ssize_t j = lo; j <= hi; ++j) {
|
||||
uint8_t * obj_j = (uint8_t *)array->data + array->size * j;
|
||||
if (array->func(obj_j, pivot) <= 0) {
|
||||
i++;
|
||||
if (j != i) {
|
||||
uint8_t * obj_i = (uint8_t *)array->data + array->size * i;
|
||||
for (size_t x = 0; x < array->size; ++x) {
|
||||
obj_j[x] ^= obj_i[x];
|
||||
obj_i[x] ^= obj_j[x];
|
||||
obj_j[x] ^= obj_i[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void quicksort(struct SortableArray * array, ssize_t lo, ssize_t hi) {
|
||||
if (lo >= 0 && hi >= 0) {
|
||||
if (lo < hi) {
|
||||
ssize_t pivot = partition(array, lo, hi);
|
||||
quicksort(array, lo, pivot - 1);
|
||||
quicksort(array, pivot + 1, hi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qsort(void * base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
|
||||
if (nmemb < 2) return;
|
||||
if (!size) return;
|
||||
struct SortableArray array = {base,size,compar};
|
||||
quicksort(&array, 0, nmemb - 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user