二进制搜索树 - 删除

时间:2011-03-31 02:24:38

标签: binary-search-tree

我正在尝试编写一个程序,它接收字符串并将它们插入树中后按字母顺序放在二叉搜索树中,用户提示删除一个单词,从而从树中删除该节点,然后按顺序输出没有该节点的树。

这一切都适用于删除功能,删除功能确实有效,但删除它的方式非常奇怪。我认为目前它删除了树的一个完整的一面,因为当我删除最后一个单词时,它通常会起作用。我将上传我的删除功能,如果需要更多功能,我可以上传其余的代码。

谢谢!

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;
    }
};

2 个答案:

答案 0 :(得分:2)

Lacqui的观点是正确的。

让我告诉您,在删除节点时,您需要将其替换为左子树中的最大节点或右子树中的最小节点。例如: 如果你看到下面的图片: enter image description here

如果要删除节点90,则需要注意将其替换为80,即左子树中的最大节点或右子树中最小节点的92。你可以保持任何一种方法。

所以算法将是: 考虑左子树:

- &gt;如果找到要删除的节点,请导航到其左子树中的最大值。

- &gt;将节点左侧指定为50,将节点右侧指定为150

- &gt; make 75-&gt; next为null并删除90

答案 1 :(得分:1)

您的左侧或右侧NULL的案例都很好。但是,遗憾的是,你们NULL都没有失败的逻辑。

如果我正在阅读您的代码(并正确理解函数replace_parent(),那么如果两个树都不为空,那么您将用Left替换当前的根。

问问自己 - Right子树中的值会发生什么?

删除节点需要执行的操作如下:

  1. 输入其中一个子树。看起来你已经选择了Left子树,所以我们将从那里开始。
  2. 按照对面分支行进行操作。在此示例中,请继续查看原始Right中的Left子树。继续,直到找到右叶节点(没有Right子树; Left没问题)
  3. tmp变量中记住右侧叶子的值。
  4. 将右侧的Left(无论是否NULL)转移到右侧叶子的位置。
  5. 获取tmp值并将其放入原始的“删除”节点。