#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int key;
struct Node* left;
struct Node* right;
int height;
} Node;
// 返回节点的高度
int getHeight(Node* node) {
if (node == NULL) {
return 0;
}
return node->height;
}
// 计算节点的平衡因子
int getBalanceFactor(Node* node) {
if (node == NULL) {
return 0;
}
return getHeight(node->left) - getHeight(node->right);
}
// 更新节点的高度
void updateHeight(Node* node) {
int leftHeight = getHeight(node->left);
int rightHeight = getHeight(node->right);
node->height = (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
// 创建一个新节点
Node* createNode(int key) {
Node* node = (Node*)malloc(sizeof(Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return node;
}
// 右旋操作
Node* rotateRight(Node* y) {
Node* x = y->left;
Node* T2 = x->right;
x->right = y;
y->left = T2;
updateHeight(y);
updateHeight(x);
return x;
}
// 左旋操作
Node* rotateLeft(Node* x) {
Node* y = x->right;
Node* T2 = y->left;
y->left = x;
x->right = T2;
updateHeight(x);
updateHeight(y);
return y;
}
// 插入节点到 AVL 树
Node* insert(Node* node, int key) {
if (node == NULL) {
return createNode(key);
}
if (key < node->key) {
node->left = insert(node->left, key);
} else if (key > node->key) {
node->right = insert(node->right, key);
} else {
return node; // 不允许插入相同的节点值
}
updateHeight(node);
int balanceFactor = getBalanceFactor(node);
// 左左情况
if (balanceFactor > 1 && key < node->left->key) {
return rotateRight(node);
}
// 右右情况
if (balanceFactor < -1 && key > node->right->key) {
return rotateLeft(node);
}
// 左右情况
if (balanceFactor > 1 && key > node->left->key) {
node->left = rotateLeft(node->left);
return rotateRight(node);
}
// 右左情况
if (balanceFactor < -1 && key < node->right->key) {
node->right = rotateRight(node->right);
return rotateLeft(node);
}
return node;
}
// 中序遍历 AVL 树(升序输出)
void inorderTraversal(Node* node) {
if (node != NULL) {
inorderTraversal(node->left);
printf("%d ", node->key);
inorderTraversal(node->right);
}
}
int main() {
Node* root = NULL;
root = insert(root, 10);
printf("%d ",root->key);
root = insert(root, 20);
printf("%d ",root->key);
root = insert(root, 30);
printf("%d ",root->key);
root = insert(root, 40);
printf("%d ",root->key);
root = insert(root, 35);
printf("%d ",root->key);
printf("AVL 树中序遍历结果:");
inorderTraversal(root);
printf("\n");
return 0;
}
按这个代码,当输入35后需要进行函数rotateLeft(root),此时根节点不是更新为3了吗,为什么打印出来还是2
还有一个问题,很多版本的AVL树的实现都不太一样,是没有一个统一的标准吗
在插入节点35后调用函数rotateLeft(root)时,根节点会更新为3而不是2。根据代码中的逻辑,当插入节点35之后,根节点10的平衡因子变为2,因此会触发左旋操作。在左旋操作中,根节点会被更新为其右子节点20,而不是3。
AVL树的实现确实存在一定的灵活性,不同的实现可能会有不同的细节。这是因为AVL树的核心概念是自平衡二叉搜索树,只要满足平衡条件,具体的实现细节可以有所不同。虽然有一些基本的标准和原则,但没有一个统一的标准来定义AVL树的实现。因此,不同的实现可能在旋转操作、平衡因子的计算、插入和删除操作的细节等方面有所不同。
AVL树只要满足平衡条件,即任何节点的左子树和右子树的高度差不超过1就可以了。