用c++实现avl树的插入和删除
时间: 2023-11-06 19:04:39 浏览: 59
AVL树的插入和删除操作都需要对树进行旋转操作来保持AVL树的平衡性。下面是C语言实现的AVL树插入和删除操作:
AVL树插入操作:
```c
// AVL树节点定义
struct AVLNode {
int key;
int height;
struct AVLNode* left;
struct AVLNode* right;
};
// 计算节点高度
int height(struct AVLNode* node) {
if (node == NULL) {
return 0;
}
return node->height;
}
// 右旋操作
struct AVLNode* rotate_right(struct AVLNode* y) {
struct AVLNode* x = y->left;
struct AVLNode* t2 = x->right;
// 执行旋转
x->right = y;
y->left = t2;
// 更新高度
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
return x;
}
// 左旋操作
struct AVLNode* rotate_left(struct AVLNode* x) {
struct AVLNode* y = x->right;
struct AVLNode* t2 = y->left;
// 执行旋转
y->left = x;
x->right = t2;
// 更新高度
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
return y;
}
// 计算平衡因子
int balance_factor(struct AVLNode* node) {
if (node == NULL) {
return 0;
}
return height(node->left) - height(node->right);
}
// 插入节点
struct AVLNode* avl_insert(struct AVLNode* node, int key) {
// 执行BST插入
if (node == NULL) {
struct AVLNode* new_node = (struct AVLNode*)malloc(sizeof(struct AVLNode));
new_node->key = key;
new_node->height = 1;
new_node->left = NULL;
new_node->right = NULL;
return new_node;
}
if (key < node->key) {
node->left = avl_insert(node->left, key);
} else if (key > node->key) {
node->right = avl_insert(node->right, key);
} else {
// key已经存在,不需要插入
return node;
}
// 更新高度
node->height = max(height(node->left), height(node->right)) + 1;
// 计算平衡因子
int bf = balance_factor(node);
// 如果平衡因子大于1,需要进行旋转操作
if (bf > 1) {
if (key < node->left->key) {
// 左左情况,执行右旋操作
return rotate_right(node);
} else {
// 左右情况,先对左子树进行左旋操作,再对根节点进行右旋操作
node->left = rotate_left(node->left);
return rotate_right(node);
}
} else if (bf < -1) {
if (key > node->right->key) {
// 右右情况,执行左旋操作
return rotate_left(node);
} else {
// 右左情况,先对右子树进行右旋操作,再对根节点进行左旋操作
node->right = rotate_right(node->right);
return rotate_left(node);
}
}
return node;
}
```
AVL树删除操作:
```c
// 查找最小值节点
struct AVLNode* find_min(struct AVLNode* node) {
if (node == NULL) {
return NULL;
}
if (node->left == NULL) {
return node;
}
return find_min(node->left);
}
// 删除节点
struct AVLNode* avl_delete(struct AVLNode* node, int key) {
// 执行BST删除
if (node == NULL) {
return NULL;
}
if (key < node->key) {
node->left = avl_delete(node->left, key);
} else if (key > node->key) {
node->right = avl_delete(node->right, key);
} else {
if (node->left == NULL || node->right == NULL) {
// 被删除节点只有一个子节点或者没有子节点
struct AVLNode* temp = node->left ? node->left : node->right;
if (temp == NULL) {
// 没有子节点,直接删除
temp = node;
node = NULL;
} else {
// 有一个子节点,用子节点替换被删除节点
*node = *temp;
}
free(temp);
} else {
// 被删除节点有两个子节点,找到右子树的最小值节点替换被删除节点
struct AVLNode* temp = find_min(node->right);
node->key = temp->key;
node->right = avl_delete(node->right, temp->key);
}
}
if (node == NULL) {
return NULL;
}
// 更新高度
node->height = max(height(node->left), height(node->right)) + 1;
// 计算平衡因子
int bf = balance_factor(node);
// 如果平衡因子大于1,需要进行旋转操作
if (bf > 1) {
if (balance_factor(node->left) >= 0) {
// 左左情况,执行右旋操作
return rotate_right(node);
} else {
// 左右情况,先对左子树进行左旋操作,再对根节点进行右旋操作
node->left = rotate_left(node->left);
return rotate_right(node);
}
} else if (bf < -1) {
if (balance_factor(node->right) <= 0) {
// 右右情况,执行左旋操作
return rotate_left(node);
} else {
// 右左情况,先对右子树进行右旋操作,再对根节点进行左旋操作
node->right = rotate_right(node->right);
return rotate_left(node);
}
}
return node;
}
```
以上是AVL树的插入和删除操作的C语言实现。需要注意的是,AVL树的插入和删除操作都需要对树进行旋转操作来保持平衡,因此这些操作的时间复杂度是O(log n)。