views:

2758

answers:

3

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

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
Adam Rosenfield
A: 

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;
Greg Rogers
I don't know why, but I'm still getting a segmentation fault :(
Doug
+1  A: 

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);
Doug