Revert "Remove the wrong heapsort implementation"

This reverts commit aa04b6ae33.
This commit is contained in:
Nils O. Selåsdal
2013-12-03 10:59:56 +01:00
parent aa04b6ae33
commit a5662a2edd
2 changed files with 62 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
#ifndef UC_HEAPSORT_H_
#define UC_HEAPSORT_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
///compare function. Needs only to return < 0 if
//the first element is less than the second
typedef int (*uc_hs_cmp)(const void *, const void *);
void
uc_heapsort(void *base, size_t count, size_t width,
uc_hs_cmp cmp);
#ifdef __cplusplus
}
#endif
#endif
+41
View File
@@ -0,0 +1,41 @@
#include <string.h>
#include "ucore/heapsort.h"
static void
uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
uc_hs_cmp cmp)
{
size_t root = start, child;
while ((root * 2 + 1) < count) {
child = root * 2 + 1;
if (child < (count - 1)
&& cmp(&base[child * width], &base[(child + 1) * width]) < 0)
child++;
if (cmp(&base[root * width], &base[child * width]) < 0) {
memcpy(base + root * width, base + child * width, width);
root = child;
} else
return;
}
}
void
uc_heapsort(void *base_, size_t count, size_t width,
uc_hs_cmp cmp)
{
int start = count / 2 - 1, end = count - 1;
unsigned char *base = base_;
while (start >= 0) {
uc_sift(base, start, count, width, cmp);
start--;
}
while (end > 0) {
memcpy(base + end * width, base, width);
uc_sift(base, 0, end, width, cmp);
end--;
}
}