c ++二进制搜索树删除

时间:2014-03-28 00:09:18

标签: c++ binary-search-tree delete-operator tree-nodes

所以,我的问题是我不明白为什么这不起作用。我在下面评论说它显然从未初始化父级。我的指针是错误的,我是否向后倾斜逻辑我到目前为止,从头开始会更好吗?这是我遇到的最困难的任务,所以任何帮助都会非常有益。

void Dictionary::remove(string word)
{
if(root == NULL)
{
    cout << "list is empty\n";
    return;
}
DictionaryNode *curr = root;
DictionaryNode *parent = NULL;`

while(curr != NULL)
{
    if(curr->word == word)
        break;
    else
    {
        parent = curr;
        if(word > curr->word)
            curr = curr->right;
        else
            curr = curr->left;
    }
}
//LEAF node.
if(curr->left == NULL && curr->right == NULL)
{
    if(parent->left == curr) // Right here is an access violation. Which doesn't //make sense.
    {
        parent->left = NULL;
    }
    else
    {
        parent->right = NULL;
    }
    delete curr;
}

/*
* Node has a single child LEFT or RIGHT
*/  
if((curr->left == NULL && curr->right != NULL) || (curr->left != NULL && curr->right == NULL))
{
    if(curr->left == NULL && curr->right != NULL)
    {
        if(parent->left == curr) //if(parent->left == curr) //says parent is //not intialized
        {
            parent->left = curr->right;
            delete curr;
        }
        else
        {
            parent->right = curr->right;
            delete curr;
        }
    }

    else
    {
        if(parent->left == curr)
        {
            parent->left = curr->left;
            delete curr;
        }
        else
        {
            parent->right = curr->left;
            delete curr;
        }
    }

}

 if (curr->left != NULL && curr->right != NULL)
{
    DictionaryNode* temp; 
    if(parent == NULL || parent->left==curr)
    {  
        temp = curr->right;
        while(temp->left!=NULL)
            temp = temp->left;
        if(parent!=NULL)
            parent->left = curr->right;
        else
            root = curr->right;
        temp->left = curr->left;
        curr->left = curr->right=NULL;
        delete curr;

    } 

    else if(parent->right==curr)
    {
        temp = curr->left;
        while(temp->right!=NULL)
            temp = temp->right;
        parent->right=curr->left;
        temp->right = curr->right;
        curr->left = curr->right=NULL;
        delete curr;
    }
  }

}

2 个答案:

答案 0 :(得分:0)

1。 我首先看到的是:

while(curr != NULL)
{
 //stuff
} 

正如它所写,似乎在你的循环结束时curr == NULL

懒惰我不得不看一下循环的内容以注意休息。在循环中使用更大的块时,中断可能更不明显。 这不是一个好习惯。

使用bool(例如:bool isNodeFound;),它便宜(一点)并使其更清晰。 虽然(curr!= NULL&amp;&amp;!isNodeFound)乍看之下更清楚你的意图,而不会看你的循环内容。

2.如果确实你没有在循环中点击中断并且curr == NULL? 你的下一条指令curr-&gt; left会失败! 好像布尔会再次有用!

if(!isNodeFound)
{
//log error if you can "cannot remove node because it is not in dictionary"
return false; //make your function a bool to return if it succeeded or not
}

尝试使用相同的心态,更清晰和测试来分析其余代码,让我知道它是否有效。

答案 1 :(得分:0)

每个人。有一天,当我需要功能来删除BST中的树节点时,我搜索了这个问题。因此,这个问题很好,我在上面的代码中进行了编辑和检查,然后代码真正成功运行了。上面的代码错过了一些实例,请按照下面的说明进行操作:

首先,已删除的节点为LEAF NODE。您错过了一个实例,该实例的节点是根节点或叶节点(即BST仅具有一个节点)。因此,parent为NULL,parent-> left / right无效。

第二个已删除节点的左侧或右侧有一个子树。因此,如果删除的节点是根节点,则这与“第一”类似。

第三个已删除的节点具有left和righr子树。您考虑过“父母”,但不应使用“ if(父母== NULL || parent-> left == curr)”,就好像parent = NULL一样,以便parent-> left无效。您应该将“ if(parent == NULL){...} else {if(parent-> left == curr)...}”。

最后,使用if ... else-if ... else而不是使用if ... if ... if,因为您删除了“ curr”,那么您将不会在任何地方知道“ curr”点,而“ if “下一个仍然会检查” curr”错误。

下面的编辑代码可满足任何人的需要,

void Dictionary::remove(string word)
{
    if(root == NULL)
    {
        cout << "list is empty\n";
        return;
    }
    DictionaryNode *curr = root;
    DictionaryNode *parent = NULL;

    while(curr != NULL)
    {
        if(curr->word == word)
            break;
        else
        {
            parent = curr;
            if(word > curr->word)
                curr = curr->right;
            else
                curr = curr->left;
        }
    }
    //LEAF node.
    if(curr->left == NULL && curr->right == NULL)
    {
        if (parent == NULL) {
            delete curr;
        } else {
            if(parent->left == curr) // Right here is an access violation. Which doesn't //make sense.
            {
                parent->left = NULL;
            }
            else
            {
                parent->right = NULL;
            }
            delete curr;
        }
    }

    /*
    * Node has a single child LEFT or RIGHT
    */  
    else if((curr->left == NULL && curr->right != NULL) || (curr->left != NULL && curr->right == NULL))
    {
        if(curr->left == NULL && curr->right != NULL)
        {
            if (parent == NULL) {
                    root = curr->right;
                    curr->right = NULL;
                    delete curr;
            } else {
                if(parent->left == curr) //if(parent->left == curr) //says parent is //not intialized
                {
                    parent->left = curr->right;
                    delete curr;
                }
                else
                {
                    parent->right = curr->right;
                    delete curr;
                }
            }
        }

        else
        {
            if (parent == NULL) {
                    root = curr->left;
                    curr->left = NULL;
                    delete curr;
            } else {
                if(parent->left == curr)
                {
                    parent->left = curr->left;
                    delete curr;
                }
                else
                {
                    parent->right = curr->left;
                    delete curr;
                }
            }
        }

    }
    else
    {
        DictionaryNode* temp; 
        if(parent == NULL)
        {  
            temp = curr->right;
            while(temp->left!=NULL)
                temp = temp->left;
            if(parent!=NULL)
                parent->left = curr->right;
            else
                root = curr->right;
            temp->left = curr->left;
            curr->left = curr->right=NULL;
            delete curr;

        } else {
            if(parent->left==curr){
                temp = curr->right;
                while(temp->left!=NULL)
                    temp = temp->left;
                if(parent!=NULL)
                    parent->left = curr->right;
                else
                    root = curr->right;
                temp->left = curr->left;
                curr->left = curr->right=NULL;
                delete curr;
            }
            else if(parent->right==curr)
            {
                temp = curr->left;
                while(temp->right!=NULL)
                    temp = temp->right;
                parent->right=curr->left;
                temp->right = curr->right;
                curr->left = curr->right=NULL;
                delete curr;
            }
        }
    }
}

希望此代码可以在其他人需要时提供帮助!