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