以下代码用于删除二叉树的节点。我已经完成了代码,我很确定问题出在最后一个问题上,否则如果"在destroy()中。我试图用最小的节点替换给定节点然后删除该给定节点。我认为应该删除()和最小的工作。当我重新打印树时,它没有任何变化。我显然是一个初学者,所以任何提示/帮助将非常感激!
void remove(Key k)
{
remove(k, root);
}
void remove(Key k, BinarySearchTreeNode<Key, Value> * n)
{
if (n)
{
if (root->key == k)
removeRoot();
else
{
//1 child
if ( (n->left != nullptr) && (k < n->key) )
{
if (k == n->left->key)
destroy(n->left, true);
else
remove(k, n->left);
}
else if (n->right && k > n->key )
{
if (k == n->right->key)
destroy(n->right, false);
else
remove(k, n->right);
}
else
{
cout << "no remove\n";
}
}
}
else
cout << "trww is empty";
}
void destroy(BinarySearchTreeNode<Key, Value> * n, bool isLeft)
{
if (n == nullptr)
{
return;
}
else if (!n->left && !n->right)
{
n->left = nullptr;
n->right = nullptr;
n->parent = nullptr;
delete n;
n = nullptr;
}
else if (!n->left && n->right)
{
isLeft ? n->parent->left = n->right : n->parent->right = n->right;
cout << "killing " << n->key << endl;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
delete n;
n = nullptr;
}
else if (n->left && !n->right)
{
isLeft ? n->parent->left = n->left : n->parent->right = n->left;
cout << "killing " << n->key << endl;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
delete n;
n = nullptr;
}
/* The program goes to the code below*/
else if (n->left && n->right)
{
BinarySearchTreeNode<Key, Value> * small = findSmallest(n->right);
if (isLeft)
n->parent->left = small;
else
n->parent->right = small;
small->parent = n->parent;
small->left = n->left;
small->right = n->right;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
//Key smallKey = small->key;
//Value smallValue = small->value;
cout << "killing " << n->key << endl;
delete n;
n = nullptr;
}
else
cout << "fail";
}
BinarySearchTreeNode<Key, Value> * findSmallest(BinarySearchTreeNode<Key, Value> * n)
{
if (!n)
return part;
else
{
if (n->left)
return findSmallest(n->left);
else
return n;
}
}
答案 0 :(得分:0)
您将节点作为指针提供给destroy()
。这意味着除了将变量更改为调用方法之外,您可以执行所有操作。
当您在n= nullptr;
中说destroy()
时,它只会更改本地变量。它不会将调用变量更改为n->right
到nullptr
,因此它仍将指向已删除对象所在的位置。
如果将参数设置为对指针(*&
)的引用,则可以更改调用变量并实际删除指向节点的指针。
它看起来像原始树的原因是因为分配给已删除节点的内存恰好还没有被重用。以后它会是你的树会导致访问错误的指针,也许会崩溃。行为未定义。