[英]Questions on an implementation of Radix sort in Java
以下Radix排序执行了四遍计数排序(从Sedgewick的Algorithms教科书中获取)(256个存储桶,32位整数,从最低有效数字开始)。
public class LSD {
private final static int BITS_PER_BYTE = 8;
// LSD sort an array of integers, treating each int as 4 bytes
// assumes integers are nonnegative
// [ 2-3x faster than Arrays.sort() ]
public static void sort(int[] a) {
int BITS = 32; // each int is 32 bits
int W = BITS / BITS_PER_BYTE; // each int is 4 bytes
int R = 1 << BITS_PER_BYTE; // each bytes is between 0 and 255
int MASK = R - 1; // 0xFF
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];
}
}
除了这部分,我了解大多数代码:
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;
}
这一段代码的目的是什么? 谢谢!
该代码块完全按照注释中的内容进行操作:
对于最高有效字节,0x80-0xFF位于0x00-0x7F之前
这样做的原因是:由于您正在使用int
,因此最高有效位是符号位。 因此,具有最高有效字节在0x80-0xFF
范围内的0x80-0xFF
是负数,因此应放在具有最高有效字节在0x00-0x7F
范围内的正数之前。
如果您要问代码块是如何实现的,这里有一个简短的想法:
由于您了解了数据的移动方式,因此我假设您了解count[]
在整个代码中的作用。 在代码块中, R
为上限,即0xFF + 1
, R / 2
为0x7F + 1
。 因此count[R] - count[R / 2]
是0x80
到0xFF
范围内的总数。 因此,通过将count[R] - count[R / 2]
的位移加到count[0 .. R / 2]
并从count[R / 2 .. R]
减去它,将有助于0x00
到0x7F
范围内的数字更高count
0x80
到0xFF
范围内的数字的值,最终导致0x80-0xFF最终位于0x00-0x7F之前 。
最后,您可能会好奇:如果第一位是符号位,为什么11111111
大于10000001
? 那不是-(127) < -(1)
吗? 这是因为在计算机系统中,我们使用2的补语而不是带符号的整数 ,因此11111111
实际上表示-1
,而10000001
实际上表示-127
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.