将链表作为参数传递时出错

时间:2015-10-02 00:54:01

标签: c linked-list bucket-sort

以下是铲斗分拣程序的代码。

typedef struct node_struct {
    double d;
    struct node_struct *next;
} node;

我正在使用插入排序来对值进行排序

void insert(double value, int index, node *B[]) {
    node *t;
    if (B[index] == NULL) {
        t = (node *)malloc(sizeof(node));
        t->d = value;
        t->next = NULL;
        B[index] = t;
    } else {
        node *p0, *p1;        
        p0 = B[index];
        p1 = p0 -> next;
        while(p1 != NULL) {
            if (p1 -> d > value) {
                break;
            }
            p1 = p1->next;
            p0 = p0->next;
    }
    t = (node *)malloc(sizeof(node));
    t->d = value;
    t->next = p1;
    p0->next = t;
}

void Bucket_Sort(double A[], int n) {
    int j, index;
    double B[n];
    node *B1;
    B1 = (node *)malloc(sizeof(node));
    for (int i = 0; i < n; i++) {
        B[i] = 0;
    }
    B1->d = A[0];
    B1->next = NULL;
    for (int i = 1; i <= n; i++) {
        index = (int) floor(n * A[i]);
        insert(A[i], index, B1);  // This part of the program is where I'm going wrong
    }
    for (int = 0; i < n; i++) {
        printf("%f \n", B[i]);
    }
}

当我尝试调用insert函数时,会出现错误,说“期望struct node **但是参数是struct node *”

但如果我调用insert函数如下:     插入(A [I],索引,及安培; B1); 然后在编译时没有给出错误但是当我运行程序时它会导致分段错误。有人可以帮我解决这个困惑吗?

1 个答案:

答案 0 :(得分:0)

您的插入函数表示b是指向节点对象的指针数组。

但是你没有传入一个指针数组,你用&amp; b1调用它,这是一个指向单个节点(不是数组)的指针。当您使用这样的数组时,通常需要传递元素数,而使用链接列表元素的指针,通常使用null来表示列表的结尾。

如果我是你,我会通过指针来处理所有事情,并摆脱[],因为你真的没有正确传递数组。例如。不要传入索引,只需将指针传递给感兴趣的对象即可。在更棘手的情况下,您可以使用**指针来指针,但这需要非常明确了解您正在做的事情。

谷歌链接列表示例,以获取如何正确处理指针的想法。你会明白的。

否则,在传递解释数组并传入计数的方式上保持一致,并在循环中使用count变量。我建议不要尝试混合使用[]表单和***范例,直到您对每个表单分别感到满意为止。

typedef struct node_struct {
    double d;
    struct node_struct *next;
} node;

void insert(double value, int index, node *b[]) {
    node *t;
    if (b[index] == NULL) {
        t = (node *)malloc(sizeof(node));
        t->d = value;
        t->next = NULL;
        b[index] = t;
    } else {
        node *p0, *p1;        
        p0 = b[index];
        p1 = p0 -> next;
        while (p1 != NULL) {
            if (p1 -> d > value) {
                break;
            }
            p1 = p1->next;
            p0 = p0->next;
    }
    t = (node *)calloc(sizeof(node), 1);
    t->d = value;
    t->next = p1;
    p0->next = t;
}

void Bucket_Sort(double a[], int n) {
    int j, index;
    double b[n];
    node *b1 = (node *)calloc(sizeof(node), 1);
    a1->d = a[0];
    b1->next = NULL;
    for (int i = 1; i <= n; i++) {
        index = (int) floor(n * a[i]);
        insert(a[i], index, b1); 
    }
    for (int = 0; i < n; i++) {
        printf("%f \n", b[i]);
    }
}

我在你的问题中格式化了程序,并在下面进一步说明。这更像是我看到用专业代码库编写的代码以及当我进行同行代码审查等时...

一些注意事项:

•如果使用calloc()而不是malloc,则缓冲区会自动归零。人们通常使用bzero()memset()来排列数组而不是for()循环。

•您可以同时声明分配变量(如B1)并节省空间/杂乱;

•您可以在for循环中声明变量类型,并将其范围限定为for循环。使其清晰并节省垂直空间。

•不要对格式化过于特殊。编程社区对它感到沮丧。在任何可敬的C编码处都有编码标准,并且非常严格,因此代码看起来干净,易读,易于理解和维护,并且一致。如果每个人都应用自己的扭曲,那么大型编码基础就会变成丑陋的维护噩梦。

•不要在指针之前和之后添加空格->没有人这样做,而且经验丰富的程序员更难阅读。在逗号之后留空格,原因与写作时相同 - 在视觉上更好地分隔项目 - 更容易调试等...

•首都用于常数。 Camel-case(首字母小写和后续单词首字母大写,例如thisIsMyVariable),变量或下划线this_is_my_variable,C中。大写字母命名数组很俗气,你几乎看不到它在专业代码中。