First of all, i know there is a similar question over here: Radix Sort for Negative Integers
however it is not duplicate to this one.
I am studying radix sorts and have a question regarding the implementation of LSD radix sort by Prof. Sedgewick and Prof. Wayne.
public static void sort(int[] a) {
final int BITS = 32; // each int is 32 bits
final int R = 1 << BITS_PER_BYTE; // each bytes is between 0 and 255
final int MASK = R - 1; // 0xFF
final int w = BITS / BITS_PER_BYTE; // each int is 4 bytes
int n = a.length;
int[] aux = new int[n];
for (int d = 0; d < w; d++) {
// compute frequency counts
int[] count = new int[R+1];
for (int i = 0; i < n; i++) {
int c = (a[i] >> BITS_PER_BYTE*d) & MASK;
count[c + 1]++;
}
// compute cumulates
for (int r = 0; r < R; r++)
count[r+1] += count[r];
// for most significant byte, 0x80-0xFF comes before 0x00-0x7F
if (d == w-1) {
int shift1 = count[R] - count[R/2];
int shift2 = count[R/2];
for (int r = 0; r < R/2; r++)
count[r] += shift1;
for (int r = R/2; r < R; r++)
count[r] -= shift2;
}
// move data
for (int i = 0; i < n; i++) {
int c = (a[i] >> BITS_PER_BYTE*d) & MASK;
aux[count[c]++] = a[i];
}
// copy back
for (int i = 0; i < n; i++)
a[i] = aux[i];
}
What is going on with the most significant byte? It is far more elegant than anything i came up with.
I am not confident in my ability to explain that block of code, it is obvious that it deals with negative numbers but i am not exactly sure how.
Could somebody explain that block of code in greater detail ?
UPDATE
I think i got additionally confused naming of variables shift1 and shift2. If we rename things a bit, and add a comment or two:
if (d == w-1) {
int totalNegatives= count[R] - count[R/2];
int totalPositives= count[R/2];
for (int r = 0; r < R/2; r++)
// all positive number must come after any negative number
count[r] += totalNegatives;
for (int r = R/2; r < R; r++)
// all negative numbers must come before any positive number
count[r] -= totalPositives;
}
this becomes easier to follow.
The idea is that first positive number can only be in position after last negative number, and all positive numbers must be after negative ones in sorted order. Therefore we simply need to add count of total negative numbers to all positives in order to ensure that positive numbers will indeed come after negatives. Same analogy for negatives numbers.