C中具有任意多个子节点的树节点
Tree node with arbitrary many child nodes in C
我正在尝试用 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 指向整数,而是指向结构节点的指针。这可行吗?
您已注释掉打印函数,但您正试图调用它来打印节点。
你得到一个分段错误,因为你没有测试 parent
节点是否有效,也没有测试 child
节点是否是一个有效的指针,也没有测试它指向的指针是否也有效. n1.child[0]
的初始化也不正确
*n1.child = &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;
}
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;}
我正在尝试用 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 指向整数,而是指向结构节点的指针。这可行吗?
您已注释掉打印函数,但您正试图调用它来打印节点。
你得到一个分段错误,因为你没有测试 parent
节点是否有效,也没有测试 child
节点是否是一个有效的指针,也没有测试它指向的指针是否也有效. n1.child[0]
的初始化也不正确
*n1.child = &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;
}
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;}