我正在尝试编写一个程序,它接收字符串并将它们插入树中后按字母顺序放在二叉搜索树中,用户提示删除一个单词,从而从树中删除该节点,然后按顺序输出没有该节点的树。
这一切都适用于删除功能,删除功能确实有效,但删除它的方式非常奇怪。我认为目前它删除了树的一个完整的一面,因为当我删除最后一个单词时,它通常会起作用。我将上传我的删除功能,如果需要更多功能,我可以上传其余的代码。
谢谢!
template<typename T> void Delete(TreeNode<T>*& root, const T& data)
{
if (root == NULL)
return;
if(data < root->Value)
return Delete(root->Left, data);
else if (root->Value > data)
return Delete(root->Right, data);
else
{
TreeNode<T>* old_root = root;
if (root->Left == NULL)
{
root = root->Right;
}
else if (root->Right == NULL)
{
root = root->Left;
}
else
{
replace_parent(old_root, old_root->Left);
}
delete old_root;
}
};
template<typename T> void replace_parent(TreeNode<T>*& old_root, TreeNode<T>*& root)
{
if (root->Right != NULL)
{
replace_parent(old_root, root->Right);
}
else
{
old_root->Value = root->Value;
old_root = root;
root = root->Left;
}
};
答案 0 :(得分:2)
Lacqui的观点是正确的。
让我告诉您,在删除节点时,您需要将其替换为左子树中的最大节点或右子树中的最小节点。例如: 如果你看到下面的图片:
如果要删除节点90,则需要注意将其替换为80,即左子树中的最大节点或右子树中最小节点的92。你可以保持任何一种方法。
所以算法将是: 考虑左子树:
- &gt;如果找到要删除的节点,请导航到其左子树中的最大值。
- &gt;将节点左侧指定为50,将节点右侧指定为150
- &gt; make 75-&gt; next为null并删除90
答案 1 :(得分:1)
您的左侧或右侧NULL
的案例都很好。但是,遗憾的是,你们NULL
都没有失败的逻辑。
如果我正在阅读您的代码(并正确理解函数replace_parent()
,那么如果两个树都不为空,那么您将用Left
替换当前的根。
问问自己 - Right
子树中的值会发生什么?
删除节点需要执行的操作如下:
Left
子树,所以我们将从那里开始。Right
中的Left
子树。继续,直到找到右叶节点(没有Right
子树; Left
没问题)tmp
变量中记住右侧叶子的值。Left
(无论是否NULL
)转移到右侧叶子的位置。tmp
值并将其放入原始的“删除”节点。