我正在尝试为整数实现右/ LSB基数排序,一旦它正常工作,我将尝试并行化它。我的顺序代码适用于无符号数,但是一旦我将负整数投入其中,它就不会看到""有符号位,最后是从0到 n 的正(排序)整数,以及从 -n 到-1的负(再次排序)整数。
这是我的代码:
public class SeqRadix {
static void radix2(int[] a) {
// 2 digit radixSort: a[]
int max = a[0];
int numBit = 2;
int n = a.length;
// a) find max value in a[]
for (int i = 1; i < n; i++){
if (a[i] > max) {
max = a[i];
}
}
while (max >= (1 << numBit)){
numBit++; // digits in max
}
// decide num of bits in bit1 and bit2
int bit1 = numBit / 2, bit2 = numBit - bit1;
int[] b = new int[n];
radixSort(a, b, bit1, 0); // first digit from a[] to b[]
radixSort(b, a, bit2, bit1);// second digit, back from b[] to a[]
} // end
/**
* Sort a[] on one digit ; number of bits = maskLen, shiftet up �shift�
* bits
*/
static void radixSort(int[] a, int[] b, int maskLen, int shift) {
int acumVal = 0, j, n = a.length;
int mask = (1 << maskLen) - 1;
int[] count = new int[mask + 1];
// b) count=the frequency of each radix value in a
for (int i = 0; i < n; i++) {
count[(a[i] >> shift) & mask]++;
}
// c) Add up in 'count' - accumulated values
for (int i = 0; i <= mask; i++) {
j = count[i];
count[i] = acumVal;
acumVal += j;
}
// c) move numbers in sorted order a to b
for (int i = 0; i < n; i++) {
b[count[(a[i] >> shift) & mask]++] = a[i];
}
}// end radixSort
}// end SekvensiellRadix
首先对LSB进行排序,然后越来越多的重要位,即2位补码/有符号位似乎没有被捕获。提前谢谢!
答案 0 :(得分:2)
您需要做的是反转符号位上的比较操作。对于每个其他位0 < 1
,但对于符号位,我们使用1 < 0
。在对0到30位进行排序时(显然对于32位整数),可以对该整数的幅度进行排序。不是绝对的,因为有一个班次,但相对于同一个符号的所有其他整数,这就是我们所需要的。
所以,如果我们有数字{5,-1,3,2,-3,-8}(为简单起见,带符号的4位):
0101 = 5
1111 = -1
0011 = 3
0010 = 2
1101 = -3
1000 = -8
排序到第2位后,我们有:
1 000 = -8
0 010 = 2
0 011 = 3
0 101 = 5
1 101 = -3
1 111 = -1
请注意,每个负数都按相对于其他负数的递增顺序排序。 (同样是积极的。)现在,为了比较符号位,我们说1 < 0
。这会将所有负数移到列表的前面,因为我们使用稳定的排序机制,所有负数都保持相对于彼此的相同位置。 (同样,对于积极因素。)
最后,我们的列表按升序排序:
1000 = -8
1101 = -3
1111 = -1
0010 = 2
0011 = 3
0101 = 5
答案 1 :(得分:1)
您只需要在对它们做出决策时通过反转第31位将所有int值转换为无符号值:
unsigned = signed ^ 0x80000000;
或者,如果您发现实施起来更方便,请反转基于第31位做出的所有决策的结果。
编辑:当您尝试查找最大值时已经开始 - 搜索最大值的方式您将永远找不到第31位设置为最大值的值。你需要使用无符号比较(java不支持语言方式),所以在比较之前翻译第31位:
// a) find max value in a[]
for (int i = 1; i < n; i++){
if ((a[i]^0x80000000) > (max^0x80000000)) {
max = a[i];
}
}