这是一个基数/桶排序混合,硬编码为9位数字。我的快速排序程序的速度是对10m数字进行排序的两倍多。我已经验证输出是正确的,它只是很慢。
代码:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<Integer> inputs = new ArrayList<>();
while (in.hasNext()) {
inputs.add(in.nextInt());
}
radixSort(inputs);
//System.out.print(toString(radixSort(inputs)));
}
public static ArrayList<Integer> radixSort(ArrayList<Integer> a) {
for (int i = 1; i <= 9; i++) {
a = bucketSort(a, i);
}
return a;
}
public static ArrayList<Integer> bucketSort(ArrayList<Integer> a, int index) {
// Creates buckets
ArrayList<ArrayList<Integer>> b = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
b.add(new ArrayList<Integer>());
}
// Sorts into buckets
for (int i = 0; i < a.size(); i++) {
b.get(key(a.get(i), index)).add(a.get(i));
}
// Concatenates buckets
ArrayList<Integer> c = new ArrayList<>();
for (int i = 0; i < b.size(); i++) {
c.addAll(b.get(i));
}
return c;
}
// Takes an integer and index and returns digit at index
public static int key(int num, int ind) {
int digit = num / (int)Math.pow(10, ind - 1);
digit = digit % 10;
return (int)digit;
}
public static String toString(ArrayList<Integer> a){
StringBuilder s = new StringBuilder();
for (int i = 0; i < a.size(); i++){
s.append(String.format("%09d\n", a.get(i)));
}
return s.toString();
}
答案 0 :(得分:0)
缓慢的主要原因是每次向每个桶阵列附加一个整数,必须再次附加才能连接桶,这涉及动态扩展阵列。
最低有效数字第一个桶排序的计数变化对第二个数组进行一次分配,其大小与原始数组相同。对于9位数示例,它可以为每个数字生成“0”,“1”,...“9”的出现次数计数,然后将计数转换为每个变量大小开头的起始索引桶,消除了连接的需要。对于9位数示例,矩阵[9] [10]可以用于计数/索引,因此只使用一次通过来生成矩阵。
维基文章:
{{3}}
示例C ++代码,使用字节大小的“数字”对32位无符号整数数组进行排序,因此计数/索引矩阵为[4] [256]。唯一的C ++部分是std :: swap(),否则就是C代码。
typedef unsigned int uint32_t;
// a is input array, b is working array
uint32_t * RadixSort(uint32_t * a, uint32_t *b, size_t count)
{
size_t mIndex[4][256] = {0}; // count / index matrix
size_t i,j,m,n;
uint32_t u;
for(i = 0; i < count; i++){ // generate histograms
u = a[i];
for(j = 0; j < 4; j++){
mIndex[j][(size_t)(u & 0xff)]++;
u >>= 8;
}
}
for(j = 0; j < 4; j++){ // convert to indices
m = 0;
for(i = 0; i < 256; i++){
n = mIndex[j][i];
mIndex[j][i] = m;
m += n;
}
}
for(j = 0; j < 4; j++){ // radix sort
for(i = 0; i < count; i++){ // sort by current lsb
u = a[i];
m = (size_t)(u>>(j<<3))&0xff;
b[mIndex[j][m]++] = u;
}
std::swap(a, b); // swap ptrs
}
return(a);
}