简体   繁体   中英

c++ Binary Search tree Deletion

So, my question is I don't understand why this doesn't work. I commented below where it is saying that parent is never initialized when it clearly is. Am I doing pointers wrong, am I getting the logic backwards am I so far off it would be better to just start from scratch? This is the most difficult assignment I have encountered so any help at all would be very beneficial.

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. First thing I see:

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

As it is written, it seems that at the end of your loop curr == NULL

Lazy me had to look at the content of your loop to notice the break. A break could be even less noticeable with a bigger block in the loop. This is not a good practice.

Use a bool (eg: bool isNodeFound;), it's cheap (one bit) and makes it more clear. while(curr != NULL && !isNodeFound) is more clear of your intentions, at first sight, without looking at the content of your loop.

2.What if indeed you don't hit the break in the loop and curr == NULL ? Your next instruction curr->left would fail! Seems like the Boolean will be useful again!

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
}

Try to analyze the rest of your code with the same state of mind, more clarity and testing, let me know if it works.

everyone. One day, I searched this question when i needed function to remove tree node in BST. So, this question is nice, i edited and checked above code then code really operated successfully. Above code missed some instances, follow me below explanations:

First, deleted node is LEAF NODE. You missed a instance that node is either root or leaf node (ie BST only have a node). So, parent is NULL and parent->left/right is invalid.

Second, deleted node has a subtree left or right. So, this is similar with First if deleted node is root.

Third, deleted node have left and righr subtree. You considered "parent" but you shouldn't use "if(parent == NULL || parent->left==curr)" as if parent = NULL so that parent->left is invalid. You should make " if(parent == NULL){...} else{if(parent->left == curr)...}".

Finally, use if...else-if...else instead of using if...if...if because you deleted "curr", then you won't know "curr" point anywhere and "if" next still will be checked with "curr" errors.

Below edited code for anyone need,

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

Hope this code that can help other people when they need!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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