C中的数组桶排序

时间:2015-01-10 13:04:52

标签: c arrays sorting

我正在尝试从txt文件中读取数字列表,然后使用Bucket sort对它们进行排序。 所以这是我的代码:

void bucketSort(int array[],int *n)
{
    int i, j;  
    int count[*n]; 
    for (i = 0; i < *n; i++)
        count[i] = 0;

    for (i = 0; i < *n; i++)
        (count[array[i]])++;

    for (i = 0, j = 0; i < *n; i++)  
        for(; count[i] > 0; (count[i])--)
            array[j++] = i; 
}   

int main(int brArg,char *arg[])
{

    FILE *ulaz;
    ulaz = fopen(arg[1], "r");

    int array[100];
    int i=0,j,k,n;


      while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;

    fclose(ulaz);    
    n=i;
    for (j = 0; j<i; j++)
    {
        printf("Broj: %d\n", array[j]);
    }

    BucketSort(array,&n); 
    for (k = 0; k<i; k++)
        printf("%d \n", array[i]);   


    return 0;
}

代码中没有错误,但是当我调用我的函数而不是排序数组时,我得到数组长度随机数(例如:2 3 5 4,排序后我得到124520 124520 124520 124520或其他一些随机数)因为我我是初学者,有人可以帮我解决我的代码以及我做错了什么吗? (抱歉英语不好)

2 个答案:

答案 0 :(得分:2)

当您尝试写入不属于您的程序的内存位置时,您的代码会显示未定义的行为。

for (i = 0; i < *n; i++)
    (count[array[i]])++;

以上循环导致了问题。您说i为4,这意味着*n也是4,array包含2 3 5 4。在上面的代码中,count*n元素的数组(在本例中为4个元素),数组的有效索引为count[0]count[1],{{1 }和count[2]。做

count[3]
count[array[i]] 为零时

是可以的,因为它与i相同。当count[2]为1时,这与i相同。之后,当count[3]为4和5时,icount[4]在您尝试写入无效的内存位置时出错。

此外,您的代码不会对值进行排序。

答案 1 :(得分:2)

正如Cool Guy正确地指出你有内存访问问题但最重要的是代码没有排序任何东西。首先,您应该阅读Bucket Sort实际如何运作。

一般来说:

  • 您可以通过某些标准在存储桶之间划分输入数据,以保证存储桶不会弄乱输入顺序
  • 使用其他排序方法对每个存储桶进行排序,或使用存储桶排序递归排序
  • 连接已排序的数据(这就是为什么第一点有限制不搞乱输入顺序的原因)

以下是您原始代码的示例,我尝试尽可能少地调整它,以便您更容易理解。此代码按范围划分3个存储区中的预定义输入数组:

  • [ - infinity] [ - 1] - &gt;第一桶
  • [0; 10] - &gt;第二桶
  • [11; infinity] - &gt;第三桶

然后在每个存储桶上执行Quicksort并连接结果。我希望这有助于理解该算法的工作原理。

#include <stdio.h>
#include <stdlib.h>

struct bucket 
{
    int count;
    int* values;
};

int compareIntegers(const void* first, const void* second)
{
    int a = *((int*)first), b =  *((int*)second);
    if (a == b)
    {
        return 0;
    }
    else if (a < b)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

void bucketSort(int array[],int n)
{
    struct bucket buckets[3];
    int i, j, k;
    for (i = 0; i < 3; i++)
    {
        buckets[i].count = 0;
        buckets[i].values = (int*)malloc(sizeof(int) * n);
    }
    // Divide the unsorted elements among 3 buckets
    // < 0    : first
    // 0 - 10 : second
    // > 10   : third
    for (i = 0; i < n; i++)
    {
        if (array[i] < 0)
        {
            buckets[0].values[buckets[0].count++] = array[i];
        }
        else if (array[i] > 10)
        {
            buckets[2].values[buckets[2].count++] = array[i];
        }
        else
        {
            buckets[1].values[buckets[1].count++] = array[i];
        }
    }
    for (k = 0, i = 0; i < 3; i++)
    {
        // Use Quicksort to sort each bucket individually
        qsort(buckets[i].values, buckets[i].count, sizeof(int), &compareIntegers);
        for (j = 0; j < buckets[i].count; j++)
        {
            array[k + j] = buckets[i].values[j];
        }
        k += buckets[i].count;
        free(buckets[i].values);
    }
}

int main(int brArg,char *arg[]) {

    int array[100] = { -5, -9, 1000, 1, -10, 0, 2, 3, 5, 4, 1234, 7 };
    int i = 12,j,k,n;

    n=i;
    for (j = 0; j<i; j++)
    {
        printf("Broj: %d\n", array[j]);
    }

    bucketSort(array, n); 
    for (k = 0; k<i; k++)
        printf("%d \n", array[k]);   


    return 0;
}