在C++中实现AVL树的插入操作,并说明其平衡性是如何维护的?请提供相应的代码示例。
时间: 2024-11-28 11:29:33 浏览: 4
AVL树是一种自平衡二叉搜索树,其中任何节点的两个子树的高度最大差别为一。为了保持这种平衡,每当一个节点被插入或删除时,都需要通过旋转操作来重新平衡树。在C++中实现AVL树的插入操作时,可以遵循以下步骤:
参考资源链接:[《数据结构与算法分析》第三版——Clifford A. Shaffer](https://wenku.csdn.net/doc/6mtn81nrui?spm=1055.2569.3001.10343)
1. 将新节点以二叉搜索树的方式插入到合适的位置。
2. 更新插入节点到根路径上每个节点的高度信息。
3. 检查插入节点到根路径上的每个节点是否平衡,即左右子树的高度差是否小于等于1。
4. 如果不平衡,根据四种旋转情况(左旋、右旋、左右旋、右左旋)之一进行旋转,以恢复平衡。
以下是一个简化的代码示例,展示了在C++中如何实现AVL树的节点结构和插入操作:
```cpp
#include <iostream>
#include <algorithm>
struct Node {
int key;
Node *left;
Node *right;
int height;
};
Node* newNode(int key) {
Node* node = new Node();
node->key = key;
node->left = nullptr;
node->right = nullptr;
node->height = 1; // 新节点被添加为叶子节点
return(node);
}
int height(Node *N) {
if (N == nullptr)
return 0;
return N->height;
}
Node* rightRotate(Node* y) {
Node* x = y->left;
Node* T2 = x->right;
// 旋转
x->right = y;
y->left = T2;
// 更新高度
y->height = std::max(height(y->left), height(y->right)) + 1;
x->height = std::max(height(x->left), height(x->right)) + 1;
// 返回新的根节点
return x;
}
Node* leftRotate(Node* x) {
Node* y = x->right;
Node* T2 = y->left;
// 旋转
y->left = x;
x->right = T2;
// 更新高度
x->height = std::max(height(x->left), height(x->right)) + 1;
y->height = std::max(height(y->left), height(y->right)) + 1;
// 返回新的根节点
return y;
}
// 获取节点的高度差异
int getBalance(Node *N) {
if (N == nullptr)
return 0;
return height(N->left) - height(N->right);
}
Node* insert(Node* node, int key) {
// 1. 正常的BST插入
if (node == nullptr)
return(newNode(key));
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else // 相等的键不允许在BST中
return node;
// 2. 更新节点的高度
node->height = 1 + std::max(height(node->left), height(node->right));
// 3. 获取平衡因子,检查是否失衡
int balance = getBalance(node);
// 如果节点失衡,有四种情况
// 左左情况
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// 右右情况
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// 左右情况
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// 右左情况
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
// 返回未改变的节点指针
return node;
}
```
在这个示例中,我们首先定义了一个AVL树节点的结构,并且创建了插入函数,该函数会递归地将新节点插入到合适的位置。插入后,我们检查节点是否失衡,并执行相应的旋转操作以恢复平衡。AVL树的平衡性维护是通过递归地更新每个节点的高度和旋转来实现的。如果你对数据结构和算法分析有更深的兴趣,我推荐阅读《数据结构与算法分析》第三版——Clifford A. Shaffer。这本书提供了丰富的概念和示例代码,可以帮助你更全面地理解AVL树的原理和实现细节。对于希望进一步学习编程和算法的读者来说,这是不可多得的学术资源。
参考资源链接:[《数据结构与算法分析》第三版——Clifford A. Shaffer](https://wenku.csdn.net/doc/6mtn81nrui?spm=1055.2569.3001.10343)
阅读全文