【问题标题】:Tree node with arbitrary many child nodes in CC中具有任意多个子节点的树节点
【发布时间】:2020-08-29 09:26:13
【问题描述】:

我正在尝试在 C 中实现一个可以有任意多个子节点的节点结构。我想通过使用指向结构的指针而不是使用数组来实现这个想法:

struct Node {
    char name[10];  // Name of the node.
    int data;       // The data it holds.
    struct Node *parent; // The parent node.
    struct Node **child; //
};

(我不知道这是最好的还是好的,但我只是在玩玩以更好地学习 C)。 我还实现了一个打印成员的print 函数:

void print(struct Node node);

(我知道这只会打印一个节点,因此它不适用于具有多个子节点的节点)。 但是,当我尝试在 main 函数中使用它时,我得到一个 segmentation fault (core dump)

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

struct Node {
    char name[10];  // Name of the node.
    int data;       // The data it holds.
    struct Node *parent; // The parent node.
    struct Node **child; //
};

void print(struct Node node) {
    printf("Name: %s\n", node.name);
    printf("Data: %d\n", node.data);
    printf("Parent: %s\n", (*node.parent).name);
    printf("Children: %s\n", (**node.child).name);
}

int main() {
    struct Node n1 = { "Parent", 1, NULL, NULL };
    struct  Node n2 = { "Child1", 2, &n1, NULL };
   
    *n1.child = &n2;
   
    print(n1);
    print(n2);
   
    return 0;
}

谁能看到我在这里做错了什么以及我应该怎么做?

亲切的问候,

编辑:

实际上我想要实现的是像这样创建子成员(我使用带有整数数组的示例来说明我的意思):

int *p = malloc(sizeof(int));
*p =1;
*(p+1)=2;

但不是 p 指向整数,而是指向指向结构节点的指针。这可行吗?

【问题讨论】:

  • n1.child 是一个空指针,因此您不能将任何内容分配给 它所指向的内存
  • 啊谢谢,那n1应该怎么初始化呢?

标签: c pointers tree structure


【解决方案1】:

你得到一个分段错误,因为你没有测试parent 节点是否有效,也没有测试child 节点是否是一个有效的指针,也不是它指向的指针也是有效的。 n1.child[0]的初始化也不正确。

  • *n1.child = &amp;n2; 具有未定义的行为,因为 n1.child 是一个空指针。
  • printf("Parent: %s\n", (*node.parent).name);n1 有未定义的行为;
  • printf("Children: %s\n", (**node.child).name);n2 有未定义的行为。

还请注意,在 C 中,将结构指针而不是结构的副本传递给诸如 print 之类的函数是惯用的。

这是一个修改后的版本,假设child,如果不是NULL,则指向NULL 终止的node 指针数组。

编辑:我添加了一个add_child 函数来说明如何从单个节点构造树。

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

struct Node {
    char name[10];  // Name of the node.
    int data;       // The data it holds.
    struct Node *parent; // The parent node.
    struct Node **child; // if not NULL, points to a NULL terminated array of pointers.
};

void print(const struct Node *node) {
    if (node) {
        printf("Name: %s\n", node->name);
        printf("Data: %d\n", node->data);
        if (node->parent) {
            printf("Parent: %s\n", node->parent->name);
        }
        if (node->child) {
            printf("Children:");
            for (int i = 0; node->child[i]; i++) {
                printf("%s %s", i > 0 ? "," : "", node->child[i]->name);
            }
            printf("\n");
        }
    }
}

// add a child node to a parent's child list.
// return 0 upon success or an error code on failure
int add_child(struct Node *parent, struct Node *chid) {
    if (parent == NULL)
        return 1;
    if (child == NULL)
        return 2;
    size_t nchild = 0;
    if (parent->child != NULL) {
        while (parent->child[nchild] != NULL)
            nchild++;
    }
    struct Node *new_child = realloc(parent->child, (nchild + 2) * sizeof(*new_child));
    if (new_child == NULL)
        return 3;
    parent->child = new_child;
    parent->child[nchild++] = child;
    parent->child[nchild] = NULL;
    child->parent = parent;
    return 0;
}

int main() {
    struct Node n1 = { "Parent", 1, NULL, NULL };
    struct Node n2 = { "Child1", 2, NULL, NULL };
    struct Node n3 = { "Child2", 3, NULL, NULL };

    add_child(&n1, &n2);
    add_child(&n1, &n3);
   
    print(&n1);
    print(&n2);
    print(&n3);
   
    return 0;
}

【讨论】:

  • 谢谢!我编辑了这篇文章以澄清我想要实现的目标(很抱歉从一开始就没有更清楚地说明这一点)。顺便说一句,最好将指向结构的指针传递给函数(在我看来,上面的打印函数中没有必要)?
  • @user202542:您的方法是正确的:我更新了答案以说明如何添加子节点。 print 函数确实可以按值取 struct Node,但它很麻烦并且可能效率低下。最好传递一个指针。请注意,在此实现中,空指针被接受并忽略,而通过值传递方法,您需要在传递它们指向的值之前检查所有节点指针。
【解决方案2】:

您已注释掉 print 函数,但您正试图调用它来打印节点。

【讨论】:

  • 对不起,这是一个错误,我编辑了它(我得到了没有评论的错误)。
【解决方案3】:

n1.child 是 NULL 指针,你在这里取消引用它 *n1.child = &n2; 这就是你得到段错误的原因,只需让子普通指针而不是双指针就可以解决问题

struct Node {
char name[10];  // Name of the node.
int data;       // The data it holds.
struct Node *parent; // The parent node.
struct Node *child; //};

void print(struct Node node) {
printf("Name: %s\n", node.name);
printf("Data: %d\n", node.data);
printf("Parent: %s\n", (*node.parent).name);
printf("Children: %s\n", (*node.child).name);}

int main() {
struct Node n1 = { "Parent", 1, NULL, NULL };
struct  Node n2 = { "Child1", 2, &n1, NULL };

n1.child = &n2;

print(n1);
print(n2);

return 0;}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2013-08-11
    • 2015-01-05
    相关资源
    最近更新 更多