簡體   English   中英

c ++二進制搜索樹刪除

[英]c++ Binary Search tree Deletion

所以,我的問題是我不明白為什么這行不通。 我在下面的評論中說,父母顯然沒有初始化過。 我是在做錯誤的指針嗎,我是在使邏輯倒退嗎?我還是相距太遠,最好還是從頭開始? 這是我遇到的最困難的任務,因此任何幫助都是非常有益的。

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

}

1.我首先看到的是:

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

如所寫,似乎在循環結束時curr == NULL

懶惰的我不得不查看循環的內容以注意到中斷。 如果循環中有較大的塊,則中斷可能更不明顯。 這不是一個好習慣。

使用布爾值(例如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
}

嘗試以相同的心態,更清晰和測試的方式分析代碼的其余部分,讓我知道它是否有效。

大家。 有一天,當我需要功能來刪除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;
            }
        }
    }
}

希望此代碼可以在需要時幫助其他人!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM