二叉搜索树删除(Inorder Pred方法)C ++

时间:2008-10-29 04:56:55

标签: c++ binary-search-tree

好的,所以我认为它已修复,但我的结果完全不一致。 我从头开始重写它,开始新鲜,这是我的结果。我没有错误,没有崩溃,它只是没有删除它们。它完全弄乱了树,给了我更多的叶子,并将所有东西混合在一起。不知道还能去哪里

template <class T>
void BST<T>::remove(struct Node<T>*& root, const T& x)
{
   Node<T>* ptr = root;
   bool found = false;
   Node<T>* parent;


   while (ptr != NULL && !found)
   {
       if (x < ptr->data)
       {
           parent = ptr;
           ptr = ptr->left;
       }
       else if (x > ptr->data)
       {
           parent = ptr;
           ptr = ptr->right;
       }
       else
           found = true;
   }

   if (found == false)
       return;
   else
   {
       if(ptr->left != NULL && ptr->right != NULL)
       {
           Node<T>* inOrderPtr = ptr->left;
           parent = ptr;
           while (inOrderPtr->right != NULL)
           {
               parent = inOrderPtr;
               inOrderPtr = inOrderPtr->right;
           }

           ptr->data = inOrderPtr->data;
           ptr = inOrderPtr;
       }
    Node<T>* subPtr = ptr->left;
    if (subPtr == NULL)
        subPtr = ptr->right;

    else if (parent->left == ptr)
        parent->left = subPtr;

    else
        parent->right = subPtr;

    delete ptr;
    }

3 个答案:

答案 0 :(得分:1)

实际发生的事情是,搜索可能会被反转,所以它实际上只是保持正确,但数据并没有真正匹配,所以它似乎会碰壁。

if (root->data < x)
        remove(root->left, x);
    else 
        remove(root->right, x);

应该是

if(x < root->data)
remove(root->left, x);
else
remove(root->right, x);

答案 1 :(得分:0)

你不应该在第三种情况下递归调用remove()(你的“不确定这是否正确”评论是这样)。在要删除的节点有两个子节点的情况下,您要做的是找到左子节点中最右边的子节点(正如您所做的那样;生成的节点存储在parent中)。此节点没有正确的子节点 - 使其右子节点是要删除的节点的正确子节点。然后只需将root变量更改为其左子项;无需更改任何节点中的data成员或递归调用remove

在图片中:

Before:
         r  <- root points here
       /  \
      /    \
     a      b
    / \    / \
   x   c  y   y
      / \
     x   d
        /
       x

After:
      a    <-- root points here
     / \
    x   c
       / \
      x   d
         / \
        x   b
           / \
          y   y

答案 2 :(得分:0)

树中发现的每个T都是唯一的吗?看起来它们来自您的代码...

看起来这应该有效:

在删除根节点的else情况下:

Node<T> *tmp_r = root->left;
Node<T> *parent = root;
while (tmp_r->right != NULL)
{
    parent = tmp_r;
    tmp_r = tmp_r->right;
}
Node<T> *tmp_l = tmp_r;
while (tmp_l->left != NULL)
    tmp_l = tmp_l->left;

tmp_l->left = root->left;
tmp_r->right = root->right;
parent->right = NULL;

parent = root;
root = tmp_r;
delete parent;