From a5662a2edd7ef1a4b7093b38c210426b97bca835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 3 Dec 2013 10:59:56 +0100 Subject: [PATCH] Revert "Remove the wrong heapsort implementation" This reverts commit aa04b6ae330b42f8a2faaa8a038ce7efbf60cb3d. --- include/ucore/heapsort.h | 21 ++++++++++++++++++++ src/heapsort.c | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/ucore/heapsort.h create mode 100644 src/heapsort.c diff --git a/include/ucore/heapsort.h b/include/ucore/heapsort.h new file mode 100644 index 0000000..c5dbf01 --- /dev/null +++ b/include/ucore/heapsort.h @@ -0,0 +1,21 @@ +#ifndef UC_HEAPSORT_H_ +#define UC_HEAPSORT_H_ + +#include + +#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 diff --git a/src/heapsort.c b/src/heapsort.c new file mode 100644 index 0000000..e291c89 --- /dev/null +++ b/src/heapsort.c @@ -0,0 +1,41 @@ +#include +#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--; + } +}