我正在尝试实现一个AVL树只是为了学习。我设法插入,但我坚持删除。我在删除叶节点时遇到问题(单子案例工作正常)。问题是,当我删除节点时,它不会从BST中删除,相反,它的值只是变为0,因此当删除节点时树永远不会失衡。我基本上做的是,如果我遇到一个没有孩子的节点,我就把它释放出来。这是函数的代码(没有重新平衡部分):
node_t *Delete ( node_t *root, int num ){
if ( !root ){
printf ("Not Found\n");
return root;
}
//=======Search for the Element=============
if ( num > root->data )
Delete ( root->right , num );
else if ( num < root->data )
Delete ( root->left , num );
//======Delete element==============
else if ( num == root->data ){
if ( root->right && root->left ){ //two child case
node_t *auxP = root->right;
while ( auxP->left ) //finding the successor
auxP=auxP->left;
root->data = auxP->data;
root->right = Delete ( root->right, auxP->data );
}
else{ //one or no child
if ( !root->right && !root->left ){ // no childs
free(root);
}
else{ //one child
node_t *auxP = ( root->right ? root->right : root->left );
*root=*auxP;
free(auxP);
}
}
}
return root;
}
如果我有这样的树:
10
/ \
5 15
/ \ \
2 6 17
我尝试删除6,它就像这样结束
10
/ \
5 15
/ \ \
2 0 17
这可能是一个明显的错误,但我找不到。任何解释为什么它不工作将不胜感激。
答案 0 :(得分:1)
删除节点时,需要更改其父节点的相应子字段。但是在您的代码中,您只传递节点到删除本身(node_t *root
),因此父节点保持不变。在单个子案例中,您可以通过将单个子项复制到要删除的节点来解决此问题,并删除单个子项。但是在叶子情况下,你没有做任何事情来修复父母的链接。
一种方法是以某种方式传递父节点,以便当节点到删除是叶子时,断开父节点的链接并将父节点的相应子节点设置为NULL
。
或者,您可以向节点定义添加父链接,以便在删除节点时,可以从中派生父链接。