AVL树节点删除

时间:2017-03-26 13:34:33

标签: c++ tree segmentation-fault avl-tree

我试图在C ++中实现AVL Tree,我实现了密钥插入没有太大问题但是在尝试删除节点时我在免​​费bug之后遇到了使用。我尝试使用gdb进行调试,但我无法找到问题,这是完整的代码。

#include <iostream>
#include <algorithm>
using namespace std;

class Node;
class AVLTree;

typedef Node* node_ptr;

class Node {
    int key;
    int height;
    node_ptr left;
    node_ptr right;
    void fix_height() {
        int hR, hL = 0;
        if (left) hL = left->height;
        if (right) hR = right->height;
        height = max(hL, hR) + 1;
    }
    int balance_factor() {
        if (left && right)
            return left->height - right->height;
        if (left && !right)
            return left->height;
        if (right && !left)
            return -right->height;
        return 0;
    }
public:
    Node(int key) :key(key), left(nullptr), right(nullptr),height(1){}
    friend class AVLTree;
};

class AVLTree {
    node_ptr mRoot;
    node_ptr insert(node_ptr node, int key) {
        if (!node) return new Node(key);
        if (node->key > key) node->left = insert(node->left, key);
        else node->right = insert(node->right, key);
        return balance(node);
    }
    node_ptr left_rotate(node_ptr X) {
        node_ptr Y = X->right;
        X->right = Y->left;
        Y->left = X;
        X->fix_height();
        Y->fix_height();
        return Y;
    }
    node_ptr right_rotate(node_ptr Y) {
        node_ptr X = Y->left;
        Y->left = X->right;
        X->right = Y;
        X->fix_height();
        Y->fix_height();
        return X;
    }
    node_ptr balance(node_ptr node) {
        node->fix_height();
        int b_factor = node->balance_factor();
        if (b_factor == 2) {
            if (node->left->balance_factor() < 0) {
                node->left = left_rotate(node->left);
            }
            return right_rotate(node);
        }
        else if (b_factor == -2) {
            if (node->right->balance_factor() > 0) {
                node->right = right_rotate(node->right);
            }
            return left_rotate(node);
        }
        return node;
    }
    node_ptr find_min(node_ptr node) {
        if (!node) return nullptr;
        if (!node->left) return node;
        else return
            find_min(node->left);
    }
    node_ptr remove_min(node_ptr node) {
        if (!node->left)
            return node->right;
        node->left = remove_min(node->left);
        return balance(node);
    }
    node_ptr remove(node_ptr node, int key) {
        if (!node) return nullptr;
        if (node->key > key)
            node->left = remove(node->left, key);
        else if (node->key < key)
            node->right = remove(node->right, key);
        else {
            node_ptr L = node->left;
            node_ptr R = node->right;
            delete node;
            if (!R) return L;
            node_ptr min = find_min(node->right);
            min->right = remove_min(R);
            min->left = L;
            return balance(min);
        }
        return balance(node);
    }
    void print_inorder(node_ptr node) {
        if (node) {
            print_inorder(node->left);
            cout << node->key << " ";
            print_inorder(node->right);
        }
    }
public:
    AVLTree() :mRoot(nullptr) {}
    void insert(int key) {
        mRoot = insert(mRoot, key);
    }
    void remove(int key) {
        mRoot = remove(mRoot, key);
    }
    void print_inorder() {
        cout << endl;
        print_inorder(mRoot);
        cout << endl;
    }

};


int main()
{
    AVLTree mtree;
    for (int i = 0; i < 3; ++i) {
        mtree.insert(i);
    }
    mtree.remove(0);
    mtree.remove(1);
    mtree.remove(2);
    mtree.print_inorder();
    return 0;
}

因此,在 remove_min()中,我使用与二叉搜索树相同的逻辑。如果子树具有右子节点,则返回该右子树的最小元素,并替换为目标节点。如果不是,则返回仅指向左子树的指针,并且当函数返回时,它平衡受干扰的节点。但不知何故删除的节点被引用,我得到分段错误。我无法弄清楚如何。有人可以帮忙吗?

0 个答案:

没有答案