Skip to content

Instantly share code, notes, and snippets.

@ian-abbott
Created September 17, 2021 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ian-abbott/7ab29fbb4fe7eaae8776eb58fdb2302a to your computer and use it in GitHub Desktop.
Save ian-abbott/7ab29fbb4fe7eaae8776eb58fdb2302a to your computer and use it in GitHub Desktop.
heapsort in C with interface like `qsort` in the standard library
#include <stddef.h>
#include "heapsort.h"
static void swapmem(void * restrict a, void * restrict b, size_t size)
{
char *x = a;
char *y = b;
char t;
while (size--) {
t = *x;
*x++ = *y;
*y++ = t;
}
}
static void heapify(char *base, size_t nmemb, size_t size, size_t root,
int (*compar)(const void *, const void *))
{
while (nmemb / 2 > root) {
size_t s = root;
size_t c = 2 * root + 1;
char *broot = base + (root * size);
char *bs = base + (s * size);
char *bc = base + (c * size);
if (compar(bc, bs) > 0) {
s = c;
bs = bc;
}
if (c < nmemb - 1) {
c++;
bc += size;
if (compar(bc, bs) > 0) {
s = c;
bs = bc;
}
}
if (s == root) {
break;
}
swapmem(bs, broot, size);
root = s;
}
}
void heapsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
char *last;
size_t i;
if (nmemb < 2) {
return;
}
i = nmemb / 2;
while (i--) {
heapify(base, nmemb, size, i, compar);
}
i = nmemb;
last = (char *)base + (i * size);
do {
i--;
last -= size;
swapmem(base, last, size);
heapify(base, i, size, 0, compar);
} while (i);
}
#ifndef HEAPSORT_H__INCLUDED
#define HEAPSORT_H__INCLUDED
#include <stddef.h>
void heapsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment