简体   繁体   中英

Problem Deleting Node of a Binary Search Tree

I am implementing a binary search tree in C ++, but the code has an error, when deleting a node with 2 children the resulting tree is not well connected, the method to delete a node with 0 or 1 child works well. This code is based in this answer: https://stackoverflow.com/a/31698320/11053027 .

Edit: For example if a add the values in this order: 17, 12, 25, and then I try delete 17 that is the root, it is deleted, so when I try to show all the elements are: 12, 25, with 25 as root. But if now I try to delete 12 it is not deleted, the problem is caused when I first deleted 17. No error message is shown.

Can you help me please. Thanks in advance. Here is the code:

    Node<E> *getSuccesor(Node<E> &node) const {
       auto *Succesor = node.right;
       while (Succesor != nullptr) {
          if (Succesor->left == nullptr) return Succesor;
          Succesor = Succesor->left;
       }
       return Succesor;
    }

    void remove(Node<E> &node) {
       if (&node == nullptr) return;
       int nChildren = numChildren(node);
       Node<E> *child;

       if (nChildren == 2) {
        child = getSuccesor(node);
        remove(*child);
        child->parent = node.parent;
        child->left = node.left;
        child->right = node.right;
        if (&node == root)
            root = child;
        else {
            if (&node == node.parent->right)
                node.parent->right = child;
            else node.parent->left = child;
        }
    } else {
        child = (node.left != nullptr ? node.left : node.right);

        if (child != nullptr)
            child->parent = node.parent;

        if (&node == root)
            root = child;
        else {
            if (&node == node.parent->left)
                node.parent->left = child;
            else node.parent->right = child;
        }
    }
    Size--;
 }

It's hard to be certain, since you haven't given us a minimal complete example , but I think the problem is here:

if (nChildren == 2) {
  child = getSuccesor(node);
  remove(*child);
  child->parent = node.parent;
  child->left = node.left;
  child->right = node.right;

So now child knows its children. But they don't know that child is now their parent. Their parent pointers still point to the defunct node (in this case, '17'), which messes up the logic in the next removal.

After those lines, add these:

if(child->left)
  child->left->parent = child;
if(child->right)
  child->right->parent = child;

EDIT: The same bug is also in the other branch of the if-else conditional, but I'm sure you can see how to fix it there too.

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