我尝试在C中实现二叉树,目前只有一个操作 - 将节点插入树中。我面临的问题是我有一个分段错误。问题来自insert
指令中的函数root = leaf
,但我无法弄清楚如何解决它。我试图以稍微不同的方式编写函数。我尝试将值传递给insert函数并在insert函数内创建二叉树的节点,而不是传递leaf
。它没有成功。
你能告诉我我的代码在哪里错了吗?谢谢
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct binaryTree
{
int data;
struct binaryTree *left;
struct binaryTree *right;
};
//the seg fault comes from the function insert
void insert(struct binaryTree *leaf,struct binaryTree *root)
{
if(root == NULL)
{
//this is the problematic instruction
root = leaf;//construct the tree if it has not been constructed before
root->left = NULL;
root->right = NULL;
}
else if(leaf->data > root->data)
{
insert(leaf, root->right);
}
else if(leaf->data < root->data)
insert(leaf,root->left);
else
{
printf("The element is in the tree already.\n");
}
}
void print(struct binaryTree *root)
{
printf("-------Print--------\n");
if(root == NULL) return;
print(root->left);
printf("%d\n", root->data);
print(root->right);
}
void createNode(int value,struct binaryTree *node)
{
printf("-------CreateNode--------\n");
node = malloc(sizeof(struct binaryTree));
node->data = value;
node->left = NULL;
node->right = NULL;
}
void destroy(struct binaryTree *root)
{
if(root != NULL)
{
destroy(root->right);
destroy(root->left);
free(root);
}
}
int main()
{
struct binaryTree *root = NULL,*a,*b,*c;
createNode(42,a);
createNode(13,b);
createNode(20,c);
insert(a,root);
insert(b,root);
insert(c,root);
print(root);
destroy(root);
return 0;
}
答案 0 :(得分:0)
问题:
在main()
开头,root
为NULL,a
未初始化。
问题是createNode(42,a);
将创建并分配一个节点,但它的地址将丢失。此函数仅设置本地参数node
,并在返回后立即丢失。此值不会复制到a
,因此会保持单元化。
然后你尝试instert(a, root)
:a
仍然是一个单位指针,root
仍然是NULL。将insert()
中的第一件事是你将单元化指针复制到root
,然后通过尝试将一些结构成员设置为NULL来取消引用这个无效指针。这会导致分段错误!
如何解决:
确保createNode()
返回值:
struct binaryTree *createNode(int value)
{
printf("-------CreateNode--------\n");
struct binaryTree *node = malloc(sizeof(struct binaryTree));
node->data = value;
node->left = NULL;
node->right = NULL;
return node;
}
并相应地改变min:
a = createNode (42);
...
您在insert()
中遇到类似的问题,并带有root
参数。你可以在这里通过重写你的函数来做类似的技术:
struct binaryTree *insert(struct binaryTree *leaf,struct binaryTree *root) {...}
但与createNode()
一样,它需要更多的gynmnastics。
因此我建议你另一个选择,作为参数传递一个指向根指针的指针:这会让你改变根poniter的值
void insert(struct binaryTree *leaf,struct binaryTree **root) // pointer to pointer
{
if(*root == NULL)
{
//this is the problematic instruction
*root = leaf;//construct the tree if it has not been constructed before
(*root)->left = NULL;
(*root)->right = NULL;
}
else if(leaf->data > (*root)->data)
{
insert(leaf, &root->right);
}
else if(leaf->data < (*root)->data)
insert(leaf,&root->left);
else
{
printf("The element is in the tree already.\n");
}
}
在主要内容中,您可以调用它:
insert(a,&root);