我正在尝试删除特定节点,但我没有看到问题所在。
实际上,我通过Find()
获取节点,然后使用Remove()
将其删除。
只要Delete()
触发,程序就会崩溃。
bool RemoveNode(int key)
{
if (IsEmpty())
return false;
Node* r = Find(key,root);
if (r==nullptr)
return false;
return Remove(r);
}
bool Remove (Node* &r)
{
if (r->left==nullptr && r->right ==nullptr)
{
delete r;
r=nullptr;
return true;
}
if (r->left==nullptr)
{
Node* temp = r->right;
delete r;
r=nullptr;
r=temp;
return true;
}
if (r->right==nullptr)
{
Node* temp = r->left;
delete r;
r=nullptr;
r=temp;
return true;
}
Node* Max = FindMax(r->left);
r->data = Max->data;
Remove(Max);
return true;
}
Node* FindMax(Node* r)
{
if(r->right==nullptr)
return r;
return FindMax(r->right);
}
Node* Find(int key, Node* &r)
{
if (r==nullptr)
return nullptr;
if (r->data==key)
return r;
if (key < r->data)
return Find(key,r->left);
else
return Find(key,r->right);
}
答案 0 :(得分:1)
显然,你的Remove()
函数旨在修改指向节点的指针,与其所在的位置无关:不是传入原始指针,而是传入对指针的引用。这样,您可以更新树的root
指针,left
或right
作为下一个组件。只要你在正确的引用中传递它,我认为代码应该可以工作。
变量r
实际上是在Remove()
中修改的,RemoveNode()
是Find()
中定义的局部变量:Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive
的结果是指针,而不是对相关的引用指针。但是,您需要修改指向节点的树结构中的指针,而不是任意局部变量。
修复方法是使用特殊版本的would be up to the task if it returned a
Find()rather than a
Node *&amp; Node** InternFind(int key) {
Node** n = &this->root;
while (*n && (*n)->key != key) {
n = &(key < (*n)->key? (*n)->left: (*n)->right);
}
return n;
}
Node *`。由于你的树似乎没有平衡,堆栈空间相对有限,我宁愿使用非递归函数。它不是返回对指针的引用,而是维护指向当前节点的指针而不是指向节点的指针:
Node** r = InternFind(key);
if (*r) {
Remove(*r);
return true;
}
else {
return false;
}
代码未经测试,可能不太正确。但是,一旦你获得了指向pinter的指针,你就可以更新它而不用处理来自哪里:
Delete()
虽然我不知道“如果delete p
触发”意味着什么,但我认为您对同一指针p
重复使用{{1}}时遇到问题。在访问陈旧节点之前,代码可能出错了。