简体   繁体   中英

Binary Search Tree Deletion (Inorder Pred method) C++

Ok so I thought it was fixed, but I'm getting totally inconsistent results. I rewrote it kind of from scratch to start fresh and here are my results. I get no errors, no crashing, it just doesn't remove them. It just totally messes up the tree and gives me a ton more leaves, and mixes everything up. Not sure where else to go

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

What actually was happening is that might searches were reversed so it would actually just keep going right but the data wasn't really matching correctly and so it would hit a wall it seems.

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

should have been

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

You shouldn't be calling remove() recursively in the third case (where your "not sure if this is right" comment is). In the case where the the node to remove has two children, what you want to do is find the right-most child of the left child (as you are doing; the resulting node is stored in parent ). This node has no right child - make it so that its right child is the right child of the node to be deleted. Then just change the root variable to be its left child; no need to change the data member in any nodes or to call remove recursively.

In pictures:

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

Are each T found in the tree unique? It looks like they are from your code...

It looks like this should work:

In the else case deleting the root node:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM