This commit is contained in:
Zengtudor 2024-12-29 10:04:06 +08:00
parent 90b8b370d7
commit c6e88be7b1

135
src/12/c13/c13_avl.cpp Normal file
View File

@ -0,0 +1,135 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Node {
int key; // 节点的关键字
int left; // 左子节点在数组中的索引
int right; // 右子节点在数组中的索引
int height; // 节点高度
Node(int k = 0) : key(k), left(-1), right(-1), height(1) {}
};
class AVLTree {
private:
vector<Node> tree; // 存储节点的数组
int root; // 根节点的索引
int size; // 当前节点数
const int MAX_SIZE = 100; // 最大节点数
// 获取节点高度
int getHeight(int index) {
if (index == -1) return 0;
return tree[index].height;
}
// 计算平衡因子
int getBalance(int index) {
if (index == -1) return 0;
return getHeight(tree[index].left) - getHeight(tree[index].right);
}
// 右旋
int rightRotate(int y) {
int x = tree[y].left;
int T2 = tree[x].right;
// 执行旋转
tree[x].right = y;
tree[y].left = T2;
// 更新高度
tree[y].height = max(getHeight(tree[y].left), getHeight(tree[y].right)) + 1;
tree[x].height = max(getHeight(tree[x].left), getHeight(tree[x].right)) + 1;
return x;
}
// 左旋
int leftRotate(int x) {
int y = tree[x].right;
int T2 = tree[y].left;
// 执行旋转
tree[y].left = x;
tree[x].right = T2;
// 更新高度
tree[x].height = max(getHeight(tree[x].left), getHeight(tree[x].right)) + 1;
tree[y].height = max(getHeight(tree[y].left), getHeight(tree[y].right)) + 1;
return y;
}
// 插入节点并返回新的根索引
int insertNode(int node, int key) {
// 1. 进行普通的 BST 插入
if (node == -1) {
if (size >= MAX_SIZE) {
cout << "Tree is full!" << endl;
return -1;
}
tree.emplace_back(Node(key));
return size++;
}
if (key < tree[node].key) {
tree[node].left = insertNode(tree[node].left, key);
}
else if (key > tree[node].key) {
tree[node].right = insertNode(tree[node].right, key);
}
else { // 相同的键不插入
return node;
}
// 2. 更新高度
tree[node].height = 1 + max(getHeight(tree[node].left), getHeight(tree[node].right));
// 3. 获取平衡因子
int balance = getBalance(node);
// 4. 如果不平衡,进行相应的旋转
// 左左情况
if (balance > 1 && key < tree[tree[node].left].key)
return rightRotate(node);
// 右右情况
if (balance < -1 && key > tree[tree[node].right].key)
return leftRotate(node);
// 左右情况
// 右左情况
return node; // 无需旋转
}
// 中序遍历
void inorderTraversal(int node) {
if (node == -1) return;
inorderTraversal(tree[node].left);
cout << tree[node].key << " ";
inorderTraversal(tree[node].right);
}
public:
AVLTree() : root(-1), size(0) {
tree.reserve(MAX_SIZE);
}
// 插入键
void insert(int key) {
root = insertNode(root, key);
}
// 中序遍历打印
void inorder() {
inorderTraversal(root);
cout << endl;
}
};