繁体   English   中英

为什么我的排序程序这么慢? (Java中的基数/存储桶排序)

[英]Why is my sorting program so slow? (radix/bucket sort in java)

这是一个基数/存储桶排序混合体,硬编码为9位数字。 我的quicksort程序对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();
}

速度慢的主要原因是一次将一个整数附加到每个存储桶数组,必须再次附加以连接存储桶,这涉及动态扩展数组。

最低有效位数的第一存储桶排序的计数变化对与原始数组大小相同的第二数组进行一次分配。 对于9位数字的示例,它可以为每个数字生成“ 0”,“ 1”,...“ 9”的出现次数计数,然后将计数转换为每个变量大小开头的起始索引桶,无需级联。 对于9位数的示例,矩阵[9] [10]可用于计数/索引,因此仅一次通过即可生成矩阵。

维基文章:

http://en.wikipedia.org/wiki/Counting_sort

示例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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM