简体   繁体   English

如何删除特定节点是二叉搜索树?

[英]How to remove Specific Node is Binary Search Tree?

I am trying to delete the specific Node but I don't see where the problem is. 我正在尝试删除特定的节点,但看不到问题出在哪里。

Actually, I get the Node through the Find() and then delete it with Remove() . 实际上,我是通过Find()获取Node的,然后使用Remove()删除它。

The program crashes whenever Delete() fires. 每当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);
}

Clearly, your Remove() function is intended to modify the pointer to the node, independent on where it is located: instead of passing in the raw pointer, you are passing in a reference to the pointer. 显然,您的Remove()函数旨在修改指向节点的指针,而与节点的位置无关:您无需传递原始指针,而是传递对指针的引用。 This way, you could update the tree's root pointer, the left or right as a component of the next. 这样,您可以更新树的root指针,将其leftright作为下一个的组成部分。 As long as you pass it in the correct reference, I think the code should work. 只要您在正确的引用中通过它,我认为代码就应该起作用。

The variable r is actually modified in Remove() which is a local variable defined in RemoveNode() : the result of Find() is a pointer, not a reference to the relevant pointer. 变量r实际上是在Remove()修改的,它是RemoveNode()定义的局部变量: Find()的结果是一个指针,而不是对相关指针的引用。 However, you need to modify the pointer in your tree structure pointing to the node, not an arbitrary local variable. 但是,您需要修改树形结构中指向节点的指针,而不是任意的局部变量。

The fix would be the use a special version of Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive 解决方法是使用Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive的特殊版本,该版本Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive Find() would be up to the task if it returned a Node*& rather than a Node*`. Find()' which correctly returns a reference to the pointer rather than the pointer itself. Your recursive Find() would be up to the task if it returned a Node *& rather than a Node *`, would be up to the task if it returned a Since your tree doesn't seem to be balanced and stack space is relatively limited, I'd rather use a non-recursive function. 由于您的树似乎并不平衡并且堆栈空间相对有限,因此我宁愿使用非递归函数。 Instead of returning a reference to a pointer it would maintain a pointer to a pointer to the current node instead of a pointer to the node: 与其返回对指针的引用,不如保留指向当前节点的指针而不是指向该节点的指针:

Node** InternFind(int key) {
    Node** n = &this->root;
    while (*n && (*n)->key != key) {
        n = &(key < (*n)->key? (*n)->left: (*n)->right);
    }
    return n;
}

The code is untested and probably not quite right. 该代码未经测试,可能不太正确。 Once you got the pointer to the pinter, however, you can just update it without dealing with where the came from: 但是,一旦获得指向该暂存器的指针,就可以对其进行更新,而无需处理其来源:

Node** r = InternFind(key);
if (*r) {
    Remove(*r);
    return true;
}
else {
    return false;
}

Although I don't know what "if Delete() fires" means, I'd assume you have a problem with duplicate uses of delete p for the same pointer p . 虽然我不知道“如果Delete()会触发”的含义,但我假设您对相同的指针p重复使用delete p存在问题。 The code probably goes wrong long before that accessing stale nodes. 该代码可能在访问失效节点之前就出错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM