Skip to content

Instantly share code, notes, and snippets.

@aragaer
Last active October 23, 2023 22:55
Show Gist options
  • Save aragaer/0150b1df7854b91774febd7afbcb1627 to your computer and use it in GitHub Desktop.
Save aragaer/0150b1df7854b91774febd7afbcb1627 to your computer and use it in GitHub Desktop.
yet another partitioning function for quicksort
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#define DEBUG
int compares = 0, swaps = 0;
void dumps(void *d, int c) {
int i;
for (i = 0; i < c; i++)
printf("%s ", *((char **) d + i));
printf("\n");
}
int (*partition)(void *, int, int, int, int (*)(const void *, const void *));
int partition_2(void *data, int low, int high, int size, int (*cmp)(const void *, const void *)) {
int i = low;
int j = high - 1;
char buf[size];
memcpy(buf, data + j * size, size);
int d = 1;
while (i < j) {
compares++;
void *addr = d ? data + size * i : data + size * j;
void *dest = d ? data + size * j : data + size * i;
if (d ^ (cmp(buf, addr) > 0)) {
swaps++;
memcpy(dest, addr, size);
d = !d;
}
if (d)
i++;
else
j--;
}
memcpy(data + size * i, buf, size);
return i;
}
int partition_1(void *data, int low, int high, int size, int (*cmp)(const void *, const void *)) {
char buf[size];
void *pivot = data + size * (high-1);
int i = low - 1, j;
for (j = low; j < high-1; j++) {
compares++;
if (cmp(data + size * j, pivot) <= 0) {
i++;
swaps++;
memcpy(buf, data + size * j, size);
memcpy(data + size * j, data + size * i, size);
memcpy(data + size * i, buf, size);
}
}
i++;
swaps++;
memcpy(buf, pivot, size);
memcpy(pivot, data + size * i, size);
memcpy(data + size * i, buf, size);
return i;
}
void qsort(void *data, size_t count, size_t size, int (*cmp)(const void *, const void *)) {
if (count < 2)
return;
int i = partition(data, 0, count, size, cmp);
#ifdef DEBUG
printf("partition at pos %d\n", i);
dumps(data, count);
#endif
qsort(data, i, size, cmp);
qsort(data + size * (i + 1), count-i-1, size, cmp);
}
int scmp(const void *a, const void *b) {
#ifdef DEBUG
printf("%s vs %s\n", *(char **)a, *(char **)b);
#endif
return strcmp(*(char **)a, *(char **)b);
}
int main(int argc, char **argv) {
int i;
char **d = malloc(sizeof(char *) * (argc-1));
memcpy(d, argv+1, (argc-1)*sizeof(char *));
partition = partition_1;
dumps(d, argc-1);
qsort(d, argc-1, sizeof(char *), scmp);
dumps(d, argc-1);
printf("Original partition: compares: %d, swaps: %d\n", compares, swaps);
compares = 0;
swaps = 0;
memcpy(d, argv+1, (argc-1)*sizeof(char *));
partition = partition_2;
qsort(d, argc-1, sizeof(char *), scmp);
dumps(d, argc-1);
printf("Modified partition: compares: %d, swaps: %d\n", compares, swaps);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment