在二叉树中实现节点插入时的C分段错误

时间:2016-02-13 00:13:57

标签: c pointers struct

我尝试在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;
}

1 个答案:

答案 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);