根据伪代码实现计数排序但生成分段错误

时间:2017-09-15 22:56:48

标签: c algorithm sorting

我已根据其伪代码(即written on the blackboard in this video explanation)实现了计数排序,但出于某种神秘的原因,它似乎无法正常工作。

每次运行此功能时,我都会遇到分段错误,但理论上它应该可以正常工作。

我的问题是:我想知道为什么下面的代码会将Segmentation fault作为输出。

void counting(int * array, int n){

    int *copy, *out, i,j, max, counter;

    out = (int*) malloc(sizeof(int) * n );

    max = array[0];


    // Find maximum value in main array and make a copy array of the same size
    for(i=0;i<n;++i) if(array[i] > max) max = array[i]; 
    copy = (int*) malloc(sizeof(int) * (max+1));


    // initialize copy array
    for(i=0;i<max;++i) copy[i] = 0;

    // count how often each value occurs
    for(i=0;i<n;++i) ++copy[array[i]];


    // perform cumulative sum over the array
    for(i=1;i<max;++i) copy[i] += copy[i-1];

    // sort
    for(i=n-1;i>=1;--i){
        out[copy[array[i]]] = array[i];
        --copy[array[i]];
    }

    // free memory
    free(copy);
    free(out);

    // copies end result to original array
    // for(i=0;i<n;++i) array[i] = out[i];

}

2 个答案:

答案 0 :(得分:0)

两个for循环都应该运行到最大值,而不是max-1。

以下更改应该有所帮助。

    for(i=0;i<=max;++i) copy[i] = 0;

    // count how often each value occurs
    for(i=0;i<n;++i) ++copy[array[i]];


    // perform cumulative sum over the array
    for(i=1;i<=max;++i) copy[i] += copy[i-1];

希望它有所帮助!

答案 1 :(得分:0)

问题似乎是因为视频中的解释假定基于1的数组索引,而C当然使用基于0的数组索引。因此,需要对循环中的许多更改以及out数组中的赋值进行更改:

void counting(int *array, int n){
    int *copy, *out, i, j, max, counter;

    out = malloc(sizeof(int) * n);
    max = array[0];
    for(i=1;i<n;++i) if(array[i] > max) max = array[i];  // 0 unnecessary
    copy = malloc(sizeof(int) * (max+1));
    for(i=0;i<=max;++i) copy[i] = 0;          // <=max for complete array
    for(i=0;i<n;++i) ++copy[array[i]];
    for(i=1;i<=max;++i) copy[i] += copy[i-1]; // <=max for complete array
    for(i=n-1;i>=0;--i){                      // >=0 for complete array
        out[copy[array[i]] - 1] = array[i];   // -1 because 0-based index
        --copy[array[i]];
    }
    for(i=0;i<n;++i) array[i] = out[i];
    free(copy);
    free(out);
}

通过这些更改,代码可以无错误地编译并提供正确的结果。