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.