【问题标题】:Getting SEGFAULT when trying to delete node from a binary search tree尝试从二叉搜索树中删除节点时获取 SEGFAULT
【发布时间】:2014-03-26 11:35:20
【问题描述】:

我在 C 中实现一个二叉搜索树。下面的代码工作正常,除了当我尝试从我的树中删除一个子树时我得到一个 SEGFAULT:

源代码:

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

struct node {
    int data;
    struct node * right, * left;
};

void insert(node ** tree, int val)
{
    node *temp = NULL;
    if(!(*tree))
    {
        temp = (node *)malloc(sizeof(node));
        temp->left = temp->right = NULL;
        temp->data = val;
        *tree = temp;
        return;
    }

    if(val < (*tree)->data)
    {
        insert(&(*tree)->left, val);
    }
    else if(val > (*tree)->data)
    {
        insert(&(*tree)->right, val);
    }

}

void print_preorder(node * tree)
{
    if (tree)
    {
        printf("%d\n",tree->data);
        print_preorder(tree->left);
        print_preorder(tree->right);
    }

}

void print_inorder(node * tree)
{
    if (tree)
    {
        print_inorder(tree->left);
        printf("%d\n",tree->data);
        print_inorder(tree->right);
    }
}

void print_postorder(node * tree)
{
    if (tree)
    {
        print_postorder(tree->left);
        print_postorder(tree->right);
        printf("%d\n",tree->data);
    }
}

 void deltree(struct node* node)
{
    if (node == NULL) return;

    struct node *r = node->right;

    deltree(node->left);
    free(node);
    deltree(r);
}

node* search(node ** tree, int val)
{
    if(!(*tree))
        return NULL;

    if(val < (*tree)->data)
    {
        return search(&((*tree)->left), val);
    }
    else if(val > (*tree)->data)
    {
        return search(&((*tree)->right), val);
    }
    else if(val == (*tree)->data)
    {
        return *tree;
    }
    return NULL;
}

void _deleteTree(struct node* node)
{
    if (node == NULL) return;

    _deleteTree(node->left);
    _deleteTree(node->right);

    printf("\nDeleting node: %d", node->data);
    free(node);
}

void deleteTree(struct node** node_ref)
{
  _deleteTree(*node_ref);
  *node_ref = NULL;
}


int  main()
{
    node *root;
    node *tmp;
    node *tmp1;

    root = NULL;
    insert(&root, 9);
    insert(&root, 4);
    insert(&root, 15);
    insert(&root, 6);
    insert(&root, 12);
    insert(&root, 17);
    insert(&root, 2);

    printf("\nPrinting tree before deletion...\n");
    print_postorder(root);

    tmp1 = search(&root, 15);

    printf("Deleting subtree...\n");
    deleteTree(&tmp1);

    printf("\nPrinting tree after deletion...\n");
    print_postorder(root);
}

输出:

Printing tree before deletion...
2
6
4
12
17
15
9

Deleting subtree...

Deleting node: 12
Deleting node: 17
Deleting node: 15
Printing tree after deletion...
2
6
4
Segmentation fault: 11

请注意,我想从整棵树中删除 subtree(尽管我的代码也应该适用于整棵树)。

【问题讨论】:

  • 在您删除节点后,节点的父节点引用已删除的节点。这就是为什么你得到一个段错误,将父母右或左设置为空。

标签: c pointers memory-management tree


【解决方案1】:

当您使用参数&amp;tmp1 调用deleteTree 时,deleteTree 函数将tmp1 设置为指向NULL。但是,这对实际树中的相应指针(即树中指向包含值 15 的节点的节点的 leftright 指针)没有影响。该指针仍然指向现在删除的节点。

改变搜索如下:

node** search(node ** tree, int val)
{
    if(!(*tree))
        return NULL;

    if(val < (*tree)->data)
    {
        return search(&((*tree)->left), val);
    }
    else if(val > (*tree)->data)
    {
        return search(&((*tree)->right), val);
    }
    else if(val == (*tree)->data)
    {
        return tree;
    }
    return NULL;
}

主要功能如下:

node** tmp1;
...
printf("Deleting subtree...\n");
deleteTree(tmp1);

【讨论】:

    【解决方案2】:

    你得到 SEGFAULT 的原因是你指向一个没有意义的地址。释放指向 15 的节点后,将 tmp1 设置为 NULL 。到目前为止,您所做的一切都是正确的,只是您没有将父级的右子指针设置为 NULL ,现在仍然指向原始地址。但是地址现在已经没有意义了。在我的电脑上,它并没有导致SEGFAULT,而是打印出一些随机数。

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多