在我的生活中,我似乎无法弄清楚我的代码在删除整个BST时出了什么问题。
我认为因为这似乎没有问题:
void emptyTree(BST **root){
if((*root)!=NULL){
emptyTree(&(*root)->left);
emptyTree(&(*root)->right);
free(*root);
}
}
然后整个问题在于树中每个节点的初始输入。任何人都可以指出这里有什么问题吗?
void insertNode(BST **root, BST *temp){
if((*root)!=NULL){
temp->parent = *root;
if(((*root)->value) < (temp->value))
insertNode(&(*root)->right,temp);
else if(((*root)->value) > (temp->value))
insertNode(&(*root)->left,temp);
else if(((*root)->value) == (temp->value)){
printf("The number %i is already in the tree.\n",temp->value);
return;
}
} else {
*root = temp;
printf("%i was added to the tree.\n",temp->value);
return;
}
}
void newNode(BST **root, int x){
BST *newnode;
newnode = (BST *)malloc(sizeof(BST));
newnode->value = x;
newnode->left = newnode->right = newnode->parent = NULL;
insertNode(root,newnode);
}
它编译,运行,它绝对完成所有功能(包括一次删除一个节点的功能)。除了“全部删除”(emptyTree)之外。它不会删除所有内容(?)。当我运行emptyTree函数时,它甚至不显示错误。当我打印整棵树时,它只会出错。
答案 0 :(得分:2)
发生错误是因为您执行释放所有数据,但忘记表明您的元素不再包含有效数据。
也就是说,删除后,所有元素&#39; left
和right
成员,您自己的root
本身仍然包含 值;它们仍然包含原始值,但这些值不再指向有效的,已分配的内存。
错误不会直接发生在emptyTree
内,因为这可以从终端节点一直到顶部,并且没有理由检查&#34; down&#34;。但是,只要您尝试打印 root
(及其后代),就会访问未分配的内存。
插入
*root = NULL;
之后的emptyTree
函数中的
free(*root);
将其修复到emptyTree
函数中,或在调用root
后将emptyTree
设置为NULL。
就个人而言,我更喜欢前者,尽管这只是一个小小的开销。这样,你只有一个函数来删除一个树,而不是递归的一个加上一个也将root设置为NULL的包装器。