高级数据结构02AVL树
文章目录
- 1.数据结构实现
- 2.代码说明
- 2.1. 插入操作:
- 2. 2删除操作:
- 2.3.平衡检查:
- 2.4. 中序遍历:
1.数据结构实现
#include <iostream>
using namespace std;
template<typename T>
class AVL {
public:
AVL() { _root = nullptr; }
// 递归实现AVL树的插入操作 BST + 平衡
void insert(const T &val) {
_root = _insert(_root, val);
}
// 递归实现AVL树的删除操作 BST + 平衡
void remove(const T &val) {
_root = _remove(_root, val);
}
// 判断一颗二叉搜索树是不是平衡树,是返回true,否则返回false
bool isAVL() {
return _isAVL(_root);
}
// 中序遍历
void inorder() {
_inorder(_root);
cout << endl;
}
private:
struct AVLNode {
AVLNode(T data = T())
: _data(data), _left(nullptr), _right(nullptr), _height(1) {}
T _data;
AVLNode *_left;
AVLNode *_right;
int _height; // 存储的就是节点的高度
};
// 返回节点的高度
int height(AVLNode *node) const {
return node == nullptr ? 0 : node->_height;
}
// 返回左右子树最高的层数
int maxHeight(AVLNode *node1, AVLNode *node2) {
return height(node1) > height(node2) ? height(node1) : height(node2);
}
// 左旋转操作 以node为根节点进行左旋转,返回旋转后的根节点
AVLNode* leftRotate(AVLNode *node) {
AVLNode *child = node->_right;
node->_right = child->_left;
child->_left = node;
node->_height = maxHeight(node->_left, node->_right) + 1;
child->_height = maxHeight(child->_left, child->_right) + 1;
return child;
}
// 右旋转操作
AVLNode* rightRotate(AVLNode *node) {
AVLNode *child = node->_left;
node->_left = child->_right;
child->_right = node;
node->_height = maxHeight(node->_left, node->_right) + 1;
child->_height = maxHeight(child->_left, child->_right) + 1;
return child;
}
// 左平衡 左-右旋转
AVLNode* leftBalance(AVLNode *node) {
leftRotate(node->_left);
return rightRotate(node);
}
// 右平衡 右-左旋转
AVLNode* rightBalance(AVLNode *node) {
rightRotate(node->_right);
return leftRotate(node);
}
// 插入辅助函数
AVLNode* _insert(AVLNode* node, const T& val) {
if (node == nullptr) {
return new AVLNode(val);
}
if (val < node->_data) {
node->_left = _insert(node->_left, val);
} else if (val > node->_data) {
node->_right = _insert(node->_right, val);
} else {
return node; // 不允许插入重复值
}
node->_height = maxHeight(node->_left, node->_right) + 1;
int balance = height(node->_left) - height(node->_right);
if (balance > 1) { // 左重
if (val < node->_left->_data) {
return rightRotate(node); // 左左
} else {
return leftBalance(node); // 左右
}
} else if (balance < -1) { // 右重
if (val > node->_right->_data) {
return leftRotate(node); // 右右
} else {
return rightBalance(node); // 右左
}
}
return node;
}
// 删除辅助函数
AVLNode* _remove(AVLNode* node, const T& val) {
if (node == nullptr) {
return node;
}
if (val < node->_data) {
node->_left = _remove(node->_left, val);
} else if (val > node->_data) {
node->_right = _remove(node->_right, val);
} else {
if (node->_left == nullptr || node->_right == nullptr) {
AVLNode* temp = node->_left ? node->_left : node->_right;
if (temp == nullptr) {
temp = node;
node = nullptr;
} else {
*node = *temp;
}
delete temp;
} else {
AVLNode* temp = node->_right;
while (temp->_left != nullptr) {
temp = temp->_left;
}
node->_data = temp->_data;
node->_right = _remove(node->_right, temp->_data);
}
}
if (node == nullptr) {
return node;
}
node->_height = maxHeight(node->_left, node->_right) + 1;
int balance = height(node->_left) - height(node->_right);
if (balance > 1) { // 左重
if (height(node->_left->_left) >= height(node->_left->_right)) {
return rightRotate(node); // 左左
} else {
return leftBalance(node); // 左右
}
} else if (balance < -1) { // 右重
if (height(node->_right->_right) >= height(node->_right->_left)) {
return leftRotate(node); // 右右
} else {
return rightBalance(node); // 右左
}
}
return node;
}
// 判断是否平衡辅助函数
bool _isAVL(AVLNode* node) {
if (node == nullptr) {
return true;
}
int balance = height(node->_left) - height(node->_right);
if (abs(balance) > 1) {
return false;
}
return _isAVL(node->_left) && _isAVL(node->_right);
}
// 中序遍历辅助函数
void _inorder(AVLNode* node) {
if (node == nullptr) {
return;
}
_inorder(node->_left);
cout << node->_data << " ";
_inorder(node->_right);
}
AVLNode *_root;
};
int main() {
AVL<int> tree;
tree.insert(10);
tree.insert(20);
tree.insert(30);
tree.insert(40);
tree.insert(50);
tree.insert(25);
cout << "Inorder traversal of the constructed AVL tree is \n";
tree.inorder();
tree.remove(30);
cout << "\nInorder traversal after deletion of 30 \n";
tree.inorder();
return 0;
}
2.代码说明
2.1. 插入操作:
• 使用递归的方式将新值插入到合适的位置。
• 插入后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 根据失衡的类型(左左、左右、右右、右左),进行相应的旋转操作。
2. 2删除操作:
• 使用递归的方式找到要删除的节点。
• 删除后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 同样根据失衡的类型进行旋转操作。
2.3.平衡检查:
• 通过计算每个节点的平衡因子来判断是否平衡。
. • 如果平衡因子的绝对值大于1,则说明树不平衡。
2.4. 中序遍历:
• 使用递归的方式进行中序遍历,输出树中的所有节点。
测试在 main 函数中,插入了一些节点并进行了删除操作,最后输出了中序遍历的结果,可以用来验证AVL树的正确性。