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