为什么此计数排序返回输入而不是排序表?

时间:2019-03-22 22:02:40

标签: c counting-sort

我正在用C编写计数排序。N是要排序的表中元素的数量,k是任何此元素可以是的最大值。但是,这段代码使我拥有与输入相同的表。怎么了?

void countingSort(int *tab, int n, int k) {
    int *counters = (int *)malloc(k * sizeof(int));
    int *result = (int *)malloc(n * sizeof(int*));
    for (int i = 0; i < k; i++) {
        counters[i] = 0;
    }
    for (int i = 0; i < n; i++) {
        counters[tab[i]]++;
    }
    int j = 0;
    for (int i = 0; i < k; i++) {
        int tmp = counters[i];
        while (tmp--) {
            result[j] = i;
            j++;
        }
    }
    tab = result;
}

2 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题:

  • int *result = (int *)malloc(n * sizeof(int*));使用了不正确的大小。数组元素类型为int,而不是int*。您应该写:

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

    或更好:

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

    还请注意,强制转换在C中是无用的,与强制执行C ++的C ++不同:

    int *result = malloc(n * sizeof(*result));
    
  • 您可以使用calloc()来避免额外的初始化循环:

    int *counters = calloc(n, sizeof(*counters));
    
  • 一个主要问题:结果数组永远不会返回给调用者:tab = result;仅修改参数值,而不修改调用者的变量。相反,您应该使用tab数组直接存储结果。

  • 您不会释放阵列,从而导致内存泄漏。

  • 您不会测试分配是否成功,如果内存不可用,则会导致未定义的行为。您应该返回一个错误状态,指示此潜在问题。

这是更正的版本:

// assuming all entries in tab are > 0 and < k
int countingSort(int *tab, int n, int k) {
    int *counters = calloc(k, sizeof(*counters));
    if (counters == NULL)
        return -1;
    for (int i = 0; i < n; i++) {
        counters[tab[i]]++;
    }
    int j = 0;
    for (int i = 0; i < k; i++) {
        int tmp = counters[i];
        while (tmp--) {
            tab[j++] = i;
        }
    }
    free(counters);
    return 0;
}

答案 1 :(得分:-1)

通过指针将制表符传递给函数。但是,您不需要更改值,而是更改变量的地址。因此,您应该将指针的地址传递给countingSort。

void countingSort(int **tab, int n, int k)