Skip to content

Instantly share code, notes, and snippets.

@kulp
Created October 20, 2012 00:25
Show Gist options
  • Save kulp/3921416 to your computer and use it in GitHub Desktop.
Save kulp/3921416 to your computer and use it in GitHub Desktop.
An in-place, unstable quicksort example in C
#include <stddef.h>
#include <string.h>
#define elem(Base, Index) \
(((char *)Base)[(Index) * width])
void swap(void *base, size_t width, size_t i0, size_t i1)
{
char temp[width];
memcpy(&temp, &elem(base,i0), width);
memcpy(&elem(base,i0), &elem(base,i1), width);
memcpy(&elem(base,i1), &temp, width);
}
void __attribute__((noinline)) quicksort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
{
if (nel < 2)
return;
// partition
size_t pi = nel >> 1; // partition index
const size_t li = nel - 1; // last index
// swap pivot to end
swap(base, width, pi, li);
size_t si = 0; // si : store index
for (size_t i = 0; i < li; i++) {
if (compar(&elem(base,i), &elem(base,li)) < 0) {
swap(base, width, i, si);
si++;
}
}
swap(base, width, si, li);
pi = si;
quicksort(&elem(base, 0), pi - 0 , width, compar);
quicksort(&elem(base,pi + 1), li - pi, width, compar);
}
int __attribute__((noinline)) cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
#if TEST
#include <stdio.h>
static struct element {
int key;
const char *str;
} data[] = {
21, "twenty-one",
34, "thirty-four",
55, "fifty-five",
144, "one hundred forty-four",
1, "one",
2, "two",
89, "eighty-nine",
3, "three",
5, "five",
8, "eight",
13, "thirteen",
};
int main(int argc, const char *argv[])
{
size_t count = sizeof data / sizeof data[0];
quicksort(data, count, sizeof data[0], cmp);
for (int i = 0; i < count; i++)
puts(data[i].str);
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment