我在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
请注意,我想从整个树中删除子树(尽管我的代码也适用于整个树)。
答案 0 :(得分:0)
当您使用参数deleteTree
致电&tmp1
时,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);
答案 1 :(得分:0)
你得到SEGFAULT的原因是你指的是一个毫无意义的地址。释放指向15的节点后,将tmp1设置为NULL。除非你没有将父对象的右子指针设置为NULL,否则你所做的一切都是正确的,现在它仍然指向原始地址。但是这个地址现在没有意义。在我的电脑上,它没有导致SEGFAULT,而是打印出一些随机数字。