0

所以,我的问题是我不明白为什么这不起作用。我在下面评论说,当它显然是时,父级永远不会被初始化。我是否做错了指针,我是否将逻辑倒退了这么远,从头开始会更好吗?这是我遇到的最困难的任务,所以任何帮助都会非常有益。

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;
    }
  }

}
4

2 回答 2

0

1. 我看到的第一件事:

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

如其所写,似乎在循环结束时 curr == NULL

懒惰的我不得不查看循环的内容才能注意到中断。如果循环中的块更大,中断可能会更不明显。这不是一个好习惯。

使用 bool(例如:bool isNodeFound;),它很便宜(一位)并且更清晰。while(curr != NULL && !isNodeFound) 乍一看更清楚您的意图,而无需查看循环的内容。

2.如果您确实没有在循环中打断并且 curr == NULL 怎么办?你的下一条指令 curr->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
}

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

于 2014-03-28T00:43:27.210 回答
0

每个人。有一天,当我需要函数来删除 BST 中的树节点时,我搜索了这个问题。所以,这个问题很好,我编辑并检查了上面的代码,然后代码真的运行成功了。上面的代码遗漏了一些实例,请按照以下说明进行操作:

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

其次,被删除的节点有一个左或右的子树。因此,如果删除的节点是根,这与 First 类似。

第三,被删除的节点有左子树和右子树。您考虑过“parent”,但不应使用“if(parent == 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;
            }
        }
    }
}

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

于 2018-10-16T10:40:42.650 回答