我创建了以下函数来从树中删除节点:
void delNode(int key, Node *root) {
if(root->data != key && root->left != NULL) {
delNode(key,root->left);
}
if(root->data != key && root->right != NULL) {
delNode(key,root->right);
}
if(root->data != key && root->left == NULL) {
return;
}
if(root->data != key && root->right == NULL) {
return;
}
if(root->data == key) {
root = NULL;
return;
}
}
我有以下遍历功能
void printInorder(Node *root) {
if(root!=NULL) {
printInorder(root->left);
printf("%d ",root->data);
printInorder(root->right);
}
}
当我删除元素&显示树,甚至显示已删除的节点。
PS:我想删除整个树,保持Node为根
答案 0 :(得分:2)
这不会删除节点,root只是对内存位置的引用
这是一个简单的解释:
所以root
就像一个箭头到一个方框,你指着箭头指向一个盒子(内存位置)说box1有一些内容。这里root = NULL
你将箭头指向没有任何空白空间,但是box1仍然包含其中的内容。
您需要做的是,清除box1的内容
free(root); //This is make memory space available, i.e deallocates the memory
此外,您删除树节点的逻辑存在缺陷/不完整(可能不完整),但我相信您已经知道了。
答案 1 :(得分:1)
您的delNode
方法不正确。从树中删除节点并不是那么简单。只考虑如何处理要删除的节点的左子树和右子树。通过分配root= NULL;
,您根本无法实现任何目标。通过使用free(root),除了永久删除当前指向的root的子节点(子树)之外,您不会实现任何目标。我已经纠正了你的方法,请参阅下文并尝试使用: -
Node* delNode(int key, Node *root) {
Node *nodeToBeDeleted=NULL
Node *predecessor = root;
if(root->data != key && root->left != NULL) {
nodeToBeDeleted = delNode(key,root->left);
if(nodeToBeDeleted){ //if we found the node to be deleted in left sub tree
if(nodeToBeDeleted->right != NULL){
root->left = nodeToBeDeleted->right;
predecessor = findPredecessor(root->right);
predecessor->left = nodeToBeDeleted->left;
}
else{
root->left = nodeToBeDeleted->left;
}
free(nodeToBeDeleted);
}
}
if(root->data != key && root->right != NULL) {
nodeToBeDeleted = delNode(key,root->right);
if(nodeToBeDeleted){ //if we found the node to be deleted in the right sub tree
if(nodeToBeDeleted->right != NULL){
root->right = nodeToBeDeleted->right;
predecessor = findPredecessor(root->right);
predecessor->left = nodeToBeDeleted->left;
}
else{
root->right = nodeToBeDeleted->left;
}
free(nodeToBeDeleted);
}
}
if(root->data != key && root->left == NULL) {
return NULL;
}
if(root->data != key && root->right == NULL) {
return NULL;
}
if(root->data == key) {
return root;
}
}
添加以下方法以查找树的前任节点
Node* findPredecessor(Node *root) {
Node *predecessor = root;
if(root!=NULL) {
predecessor = findPredecessor(root->left);
}
if(predecessor == NULL)
return root;
else
return predecessor;
}
答案 2 :(得分:0)
我需要先释放节点然后再使用delete。我的坏。