簡體   English   中英

嘗試從二進制搜索樹中刪除節點時獲取SEGFAULT

[英]Getting SEGFAULT when trying to delete node from a binary search tree

我正在用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

請注意,我想從整個樹中刪除樹(盡管我的代碼也應適用於整個樹)。

當使用參數&tmp1調用deleteTree時, deleteTree函數deleteTree tmp1設置為指向NULL 但是,這對實際樹中的相應指針(即,樹中指向包含值15的節點的節點的left指針或right指針)沒有影響。 該指針仍指向現在已刪除的節點。

更改搜索,如下所示:

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

之所以得到SEGFAULT,是因為您指向的地址沒有意義。 釋放指向15的節點后,將tmp1設置為NULL。到目前為止,您所做的一切都是正確的,只是您也沒有將父級的右子指針設置為NULL,該指針現在仍指向原始地址。 但是該地址現在變得毫無意義。在我的計算機上,它沒有引起SEGFAULT,但它卻打印出一些隨機數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM