Fix heapsort, add test
This commit is contained in:
+15
-11
@@ -3,39 +3,43 @@
|
||||
|
||||
static void
|
||||
uc_sift(unsigned char *base, size_t start, size_t count, size_t width,
|
||||
uc_hs_cmp cmp)
|
||||
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
||||
{
|
||||
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 (child < (count - 1)) {
|
||||
int rc = cmp(&base[child * width], &base[(child + 1) * width], cookie);
|
||||
if (rc < 0) {
|
||||
child++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmp(&base[root * width], &base[child * width]) < 0) {
|
||||
memcpy(base + root * width, base + child * width, width);
|
||||
if (cmp(&base[root * width], &base[child * width], cookie) < 0) {
|
||||
swap(base + root * width, base + child * width);
|
||||
root = child;
|
||||
} else
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
uc_heapsort(void *base_, size_t count, size_t width,
|
||||
uc_hs_cmp cmp)
|
||||
uc_hs_cmp cmp, uc_hs_swp swap, void *cookie)
|
||||
{
|
||||
int start = count / 2 - 1, end = count - 1;
|
||||
unsigned char *base = base_;
|
||||
|
||||
while (start >= 0) {
|
||||
uc_sift(base, start, count, width, cmp);
|
||||
uc_sift(base, start, count, width, cmp, swap, cookie);
|
||||
start--;
|
||||
}
|
||||
|
||||
while (end > 0) {
|
||||
memcpy(base + end * width, base, width);
|
||||
uc_sift(base, 0, end, width, cmp);
|
||||
swap(base + end * width, base);
|
||||
uc_sift(base, 0, end, width, cmp, swap, cookie);
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user