简体   繁体   中英

Binary search tree deletion (C++)

I'm having trouble implementing a binary search tree deletion algorithm on C++. If I try deleting the root, or direct children of the root, it works correctly. But it does not work for deeper levels (just outputs the same tree without any deletion). What is wrong with my code?

typedef struct Node {
    int key;
    Node *left = NULL;
    Node *right = NULL;
} Node;

...

/*
 * Delete <key> from BST rooted at <node> and return modified <node>.
 */
Node* BST::pop(Node *node, int key) {
    // If <node> is a null pointer, return.
    // If <node> doesn't contain the key, traverse down the tree.
    // If <node> contains the key, perform deletion.
    if (node == NULL) {
    } else if (key < node->key) {
        node->left = pop(node->left, key);
    } else if (key > root->key) {
        node->right = pop(node->right, key);
    } else {
        // If <node> is a leaf, just delete it
        if (node->left == NULL && node->right == NULL) {
            delete node; // deallocate memory (note: node still points to a memory address!)
            node = NULL; // node points to null
        } 
        // If <node> has a single child, replace <node> with its child
        else if (node->left == NULL && node->right != NULL) {
            Node *tmp = node;
            node = node->right;
            delete tmp;
            tmp = NULL;
        } else if (node->right == NULL && node->left != NULL) {
            Node *tmp = node;
            node = node->left;
            delete tmp;
            tmp = NULL;
        } else {
            node->key = findMax(node->left);
            node->left = pop(node->left, node->key);
        }
    }
    return node;
}

int BST::findMax(Node *root) {
    if (root->left == NULL && root->right == NULL) {
        return root->key;
    } else {
        int max = root->key;
        if (root->left != NULL) {
            int leftMax = findMax(root->left);
            if (leftMax > max) {
                max = leftMax;
            }
        }
        if (root->right != NULL) {
            int rightMax = findMax(root->right);
            if (rightMax > max) {
                max = rightMax;
            }
        }
        return max;
    }
}

A couple of things:

  • Second else if should be else if (key > node->key)
  • Your findMax function is exceptionally complex. The max in a BST from some root is really just traversing right children until there are no more right children (because anything in the left subtree must be less than the key you are currently evaluating, so leftMax can never be > max). Therefore it could be

     int BST::findMax(Node *root) { int max = root->key; while (root->right != NULL) { root = root->right; max = root->key; } return max; } 
  • As long as the tree does not need to remain balanced, your general algorithm of just removing in case of a leaf, swapping the lone child if there is only one, and in the case of two children finding an inorder neighbor, swapping and deleting that node should be sound (not sure if you found this link, but: http://quiz.geeksforgeeks.org/binary-search-tree-set-2-delete/ )

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