【问题标题】:Binary Search Tree Deletion (Inorder Pred method) C++二叉搜索树删除(Inorder Pred 方法)C++
【发布时间】:2015-07-01 21:24:23
【问题描述】:

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

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

【问题讨论】:

    标签: c++ binary-search-tree


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      在树中找到的每个 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;
      

      【讨论】:

      • 我不知道为什么,但我仍然遇到分段错误:(
      【解决方案3】:

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

      在图片中:

      前: r

      【讨论】:

        猜你喜欢
        • 2014-04-19
        • 2013-11-21
        • 1970-01-01
        • 2013-04-09
        • 1970-01-01
        • 2017-06-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多