#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
typedef union {
struct {
uint32_t c8[256];
uint32_t c7[256];
uint32_t c6[256];
uint32_t c5[256];
uint32_t c4[256];
uint32_t c3[256];
uint32_t c2[256];
uint32_t c1[256];
};
uint32_t counts[256 * 8];
} rscounts_t;
uint64_t * radixSort(uint64_t * array, uint32_t size) {
rscounts_t counts;
memset(&counts
, 0, 256 * 8 * sizeof(uint32_t)); uint64_t * cpy
= (uint64_t *)malloc(size
* sizeof(uint64_t)); uint32_t o8=0, o7=0, o6=0, o5=0, o4=0, o3=0, o2=0, o1=0;
uint32_t t8, t7, t6, t5, t4, t3, t2, t1;
uint32_t x;
// calculate counts
for(x = 0; x < size; x++) {
t8 = array[x] & 0xff;
t7 = (array[x] >> 8) & 0xff;
t6 = (array[x] >> 16) & 0xff;
t5 = (array[x] >> 24) & 0xff;
t4 = (array[x] >> 32) & 0xff;
t3 = (array[x] >> 40) & 0xff;
t2 = (array[x] >> 48) & 0xff;
t1 = (array[x] >> 56) & 0xff;
counts.c8[t8]++;
counts.c7[t7]++;
counts.c6[t6]++;
counts.c5[t5]++;
counts.c4[t4]++;
counts.c3[t3]++;
counts.c2[t2]++;
counts.c1[t1]++;
}
// convert counts to offsets
for(x = 0; x < 256; x++) {
t8 = o8 + counts.c8[x];
t7 = o7 + counts.c7[x];
t6 = o6 + counts.c6[x];
t5 = o5 + counts.c5[x];
t4 = o4 + counts.c4[x];
t3 = o3 + counts.c3[x];
t2 = o2 + counts.c2[x];
t1 = o1 + counts.c1[x];
counts.c8[x] = o8;
counts.c7[x] = o7;
counts.c6[x] = o6;
counts.c5[x] = o5;
counts.c4[x] = o4;
counts.c3[x] = o3;
counts.c2[x] = o2;
counts.c1[x] = o1;
o8 = t8;
o7 = t7;
o6 = t6;
o5 = t5;
o4 = t4;
o3 = t3;
o2 = t2;
o1 = t1;
}
// radix
for(x = 0; x < size; x++) {
t8 = array[x] & 0xff;
cpy[counts.c8[t8]] = array[x];
counts.c8[t8]++;
}
for(x = 0; x < size; x++) {
t7 = (cpy[x] >> 8) & 0xff;
array[counts.c7[t7]] = cpy[x];
counts.c7[t7]++;
}
for(x = 0; x < size; x++) {
t6 = (array[x] >> 16) & 0xff;
cpy[counts.c6[t6]] = array[x];
counts.c6[t6]++;
}
for(x = 0; x < size; x++) {
t5 = (cpy[x] >> 24) & 0xff;
array[counts.c5[t5]] = cpy[x];
counts.c5[t5]++;
}
for(x = 0; x < size; x++) {
t4 = (array[x] >> 32) & 0xff;
cpy[counts.c4[t4]] = array[x];
counts.c4[t4]++;
}
for(x = 0; x < size; x++) {
t3 = (cpy[x] >> 40) & 0xff;
array[counts.c3[t3]] = cpy[x];
counts.c3[t3]++;
}
for(x = 0; x < size; x++) {
t2 = (array[x] >> 48) & 0xff;
cpy[counts.c2[t2]] = array[x];
counts.c2[t2]++;
}
for(x = 0; x < size; x++) {
t1 = (cpy[x] >> 56) & 0xff;
array[counts.c1[t1]] = cpy[x];
counts.c1[t1]++;
}
return array;
}
int main(void) {
uint32_t size = 1000;
uint32_t x;
uint64_t * array
= (uint64_t *)malloc(size
* sizeof(uint64_t)); for(x = 0; x < size; x++) {
array[x] = size - x;
}
printf("%" PRIu64
", %" PRIu64
"\n", array
[0], array
[size
- 1]); array = radixSort(array, size);
printf("%" PRIu64
", %" PRIu64
"\n", array
[0], array
[size
- 1]); return 0;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGludC5oPgojaW5jbHVkZSA8aW50dHlwZXMuaD4KCnR5cGVkZWYgdW5pb24gewoJc3RydWN0IHsKCQl1aW50MzJfdCBjOFsyNTZdOwoJCXVpbnQzMl90IGM3WzI1Nl07CgkJdWludDMyX3QgYzZbMjU2XTsKCQl1aW50MzJfdCBjNVsyNTZdOwoJCXVpbnQzMl90IGM0WzI1Nl07CgkJdWludDMyX3QgYzNbMjU2XTsKCQl1aW50MzJfdCBjMlsyNTZdOwoJCXVpbnQzMl90IGMxWzI1Nl07Cgl9OwoJdWludDMyX3QgY291bnRzWzI1NiAqIDhdOwp9IHJzY291bnRzX3Q7Cgp1aW50NjRfdCAqIHJhZGl4U29ydCh1aW50NjRfdCAqIGFycmF5LCB1aW50MzJfdCBzaXplKSB7Cglyc2NvdW50c190IGNvdW50czsKCW1lbXNldCgmY291bnRzLCAwLCAyNTYgKiA4ICogc2l6ZW9mKHVpbnQzMl90KSk7Cgl1aW50NjRfdCAqIGNweSA9ICh1aW50NjRfdCAqKW1hbGxvYyhzaXplICogc2l6ZW9mKHVpbnQ2NF90KSk7Cgl1aW50MzJfdCBvOD0wLCBvNz0wLCBvNj0wLCBvNT0wLCBvND0wLCBvMz0wLCBvMj0wLCBvMT0wOwoJdWludDMyX3QgdDgsIHQ3LCB0NiwgdDUsIHQ0LCB0MywgdDIsIHQxOwoJdWludDMyX3QgeDsKCS8vIGNhbGN1bGF0ZSBjb3VudHMKCWZvcih4ID0gMDsgeCA8IHNpemU7IHgrKykgewoJCXQ4ID0gYXJyYXlbeF0gJiAweGZmOwoJCXQ3ID0gKGFycmF5W3hdID4+IDgpICYgMHhmZjsKCQl0NiA9IChhcnJheVt4XSA+PiAxNikgJiAweGZmOwoJCXQ1ID0gKGFycmF5W3hdID4+IDI0KSAmIDB4ZmY7CgkJdDQgPSAoYXJyYXlbeF0gPj4gMzIpICYgMHhmZjsKCQl0MyA9IChhcnJheVt4XSA+PiA0MCkgJiAweGZmOwoJCXQyID0gKGFycmF5W3hdID4+IDQ4KSAmIDB4ZmY7CgkJdDEgPSAoYXJyYXlbeF0gPj4gNTYpICYgMHhmZjsKCQljb3VudHMuYzhbdDhdKys7CgkJY291bnRzLmM3W3Q3XSsrOwoJCWNvdW50cy5jNlt0Nl0rKzsKCQljb3VudHMuYzVbdDVdKys7CgkJY291bnRzLmM0W3Q0XSsrOwoJCWNvdW50cy5jM1t0M10rKzsKCQljb3VudHMuYzJbdDJdKys7CgkJY291bnRzLmMxW3QxXSsrOwoJfQoJLy8gY29udmVydCBjb3VudHMgdG8gb2Zmc2V0cwoJZm9yKHggPSAwOyB4IDwgMjU2OyB4KyspIHsKCQl0OCA9IG84ICsgY291bnRzLmM4W3hdOwoJCXQ3ID0gbzcgKyBjb3VudHMuYzdbeF07CgkJdDYgPSBvNiArIGNvdW50cy5jNlt4XTsKCQl0NSA9IG81ICsgY291bnRzLmM1W3hdOwoJCXQ0ID0gbzQgKyBjb3VudHMuYzRbeF07CgkJdDMgPSBvMyArIGNvdW50cy5jM1t4XTsKCQl0MiA9IG8yICsgY291bnRzLmMyW3hdOwoJCXQxID0gbzEgKyBjb3VudHMuYzFbeF07CgkJY291bnRzLmM4W3hdID0gbzg7CgkJY291bnRzLmM3W3hdID0gbzc7CgkJY291bnRzLmM2W3hdID0gbzY7CgkJY291bnRzLmM1W3hdID0gbzU7CgkJY291bnRzLmM0W3hdID0gbzQ7CgkJY291bnRzLmMzW3hdID0gbzM7CgkJY291bnRzLmMyW3hdID0gbzI7CgkJY291bnRzLmMxW3hdID0gbzE7CgkJbzggPSB0ODsgCgkJbzcgPSB0NzsgCgkJbzYgPSB0NjsgCgkJbzUgPSB0NTsgCgkJbzQgPSB0NDsgCgkJbzMgPSB0MzsgCgkJbzIgPSB0MjsgCgkJbzEgPSB0MTsKCX0KCS8vIHJhZGl4Cglmb3IoeCA9IDA7IHggPCBzaXplOyB4KyspIHsKCQl0OCA9IGFycmF5W3hdICYgMHhmZjsKCQljcHlbY291bnRzLmM4W3Q4XV0gPSBhcnJheVt4XTsKCQljb3VudHMuYzhbdDhdKys7Cgl9Cglmb3IoeCA9IDA7IHggPCBzaXplOyB4KyspIHsKCQl0NyA9IChjcHlbeF0gPj4gOCkgJiAweGZmOwoJCWFycmF5W2NvdW50cy5jN1t0N11dID0gY3B5W3hdOwoJCWNvdW50cy5jN1t0N10rKzsKCX0KCWZvcih4ID0gMDsgeCA8IHNpemU7IHgrKykgewoJCXQ2ID0gKGFycmF5W3hdID4+IDE2KSAmIDB4ZmY7CgkJY3B5W2NvdW50cy5jNlt0Nl1dID0gYXJyYXlbeF07CgkJY291bnRzLmM2W3Q2XSsrOwoJfQoJZm9yKHggPSAwOyB4IDwgc2l6ZTsgeCsrKSB7CgkJdDUgPSAoY3B5W3hdID4+IDI0KSAmIDB4ZmY7CgkJYXJyYXlbY291bnRzLmM1W3Q1XV0gPSBjcHlbeF07CgkJY291bnRzLmM1W3Q1XSsrOwoJfQoJZm9yKHggPSAwOyB4IDwgc2l6ZTsgeCsrKSB7CgkJdDQgPSAoYXJyYXlbeF0gPj4gMzIpICYgMHhmZjsKCQljcHlbY291bnRzLmM0W3Q0XV0gPSBhcnJheVt4XTsKCQljb3VudHMuYzRbdDRdKys7Cgl9Cglmb3IoeCA9IDA7IHggPCBzaXplOyB4KyspIHsKCQl0MyA9IChjcHlbeF0gPj4gNDApICYgMHhmZjsKCQlhcnJheVtjb3VudHMuYzNbdDNdXSA9IGNweVt4XTsKCQljb3VudHMuYzNbdDNdKys7Cgl9Cglmb3IoeCA9IDA7IHggPCBzaXplOyB4KyspIHsKCQl0MiA9IChhcnJheVt4XSA+PiA0OCkgJiAweGZmOwoJCWNweVtjb3VudHMuYzJbdDJdXSA9IGFycmF5W3hdOwoJCWNvdW50cy5jMlt0Ml0rKzsKCX0KCWZvcih4ID0gMDsgeCA8IHNpemU7IHgrKykgewoJCXQxID0gKGNweVt4XSA+PiA1NikgJiAweGZmOwoJCWFycmF5W2NvdW50cy5jMVt0MV1dID0gY3B5W3hdOwoJCWNvdW50cy5jMVt0MV0rKzsKCX0KCWZyZWUoY3B5KTsKCXJldHVybiBhcnJheTsKfQppbnQgbWFpbih2b2lkKSB7Cgl1aW50MzJfdCBzaXplID0gMTAwMDsKCXVpbnQzMl90IHg7Cgl1aW50NjRfdCAqIGFycmF5ID0gKHVpbnQ2NF90ICopbWFsbG9jKHNpemUgKiBzaXplb2YodWludDY0X3QpKTsKCWZvcih4ID0gMDsgeCA8IHNpemU7IHgrKykgewoJCWFycmF5W3hdID0gc2l6ZSAtIHg7Cgl9CglwcmludGYoIiUiIFBSSXU2NCAiLCAlIiBQUkl1NjQgIlxuIiwgYXJyYXlbMF0sIGFycmF5W3NpemUgLSAxXSk7CglhcnJheSA9IHJhZGl4U29ydChhcnJheSwgc2l6ZSk7CglwcmludGYoIiUiIFBSSXU2NCAiLCAlIiBQUkl1NjQgIlxuIiwgYXJyYXlbMF0sIGFycmF5W3NpemUgLSAxXSk7CglyZXR1cm4gMDsKfQo=