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

标签 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]);
    }
}

当我尝试调用插入函数时,出现错误,提示“期望结构节点 ** 但参数的类型为结构节点 *”

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

最佳答案

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

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

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

Google 链接列表示例,了解如何使用指针正确处理该问题。你就会明白了。

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

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 编码场所都有编码标准,而且非常严格,因此代码看起来干净、可读、易于理解和维护,并且一致。如果每个人都采用自己的方式,那么庞大的编码库就会成为丑陋的维护噩梦。

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

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

关于c - 将链表作为参数传递时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32898997/

相关文章:

c++ - 求 1 的总数

c - 如何将两个寄存器的 2 的补码值读入一个 int

c - 由 2 个结构组成的链表。接入节点

sorting - ElasticSearch-按子聚合排序

c#实现桶排序算法

c - 将结构传递给函数的问题

c++ - scanf 读取格式化输入

c++ - c++数据输入并在列表的结构中读回数组

c++ - 在链表中,析构函数以什么顺序删除节点?

sorting - 我什么时候应该选择桶排序而不是其他排序算法?