简体   繁体   English

二进制搜索树删除(C ++)

[英]Binary search tree deletion (C++)

I'm having trouble implementing a binary search tree deletion algorithm on C++. 我在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) 第二个if应该是else if (key > node->key)
  • Your findMax function is exceptionally complex. 您的findMax函数异常复杂。 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). 从某个根开始,BST中的最大值实际上只是遍历正确的子级,直到没有更多的正确的子级为止(因为左子树中的任何内容都必须小于当前评估的键,因此leftMax永远不能大于> 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/ ) 只要树不需要保持平衡,一般的算法就是在叶子出现的情况下删除,如果只有一个,则交换唯一的孩子,并且在两个孩子找到有序邻居的情况下,交换并删除该孩子。节点应该是健全的(不确定是否找到此链接,但是: http : //quiz.geeksforgeeks.org/binary-search-tree-set-2-delete/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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