本专栏持续输出数据结构题目集,欢迎订阅。
题目
将给定的一系列数字插入初始为空的 AVL 树,请你输出最后生成的 AVL 树的根结点的值。
输入格式:
输入的第一行给出一个正整数 n(≤20),随后一行给出 n 个整形 int 范围内的、不同的整数,其间以空格分隔。
输出格式:
在一行中输出顺序插入上述整数到一棵初始为空的 AVL 树后,该树的根结点的值。
输入样例1:
5
88 70 61 96 120
输出样例1:
70
输入样例2:
7
88 70 61 96 120 90 65
输出样例2:
88
代码
#include <stdio.h>
#include <stdlib.h>
// AVL树节点结构
typedef struct Node {
int data;
struct Node *left;
struct Node *right;
int height; // 节点高度,用于平衡判断
} Node;
// 创建新节点
Node* createNode(int data) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->height = 1; // 新节点初始高度为1
return node;
}
// 获取节点高度
int getHeight(Node* node) {
if (node == NULL)
return 0;
return node->height;
}
// 计算平衡因子(左子树高度 - 右子树高度)
int getBalance(Node* node) {
if (node == NULL)
return 0;
return getHeight(node->left) - getHeight(node->right);
}
// 更新节点高度
void updateHeight(Node* node) {
if (node == NULL) return;
int leftHeight = getHeight(node->left);
int rightHeight = getHeight(node->right);
node->height = (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
// 右旋转操作
Node* rightRotate(Node* y) {
Node* x = y->left;
Node* T2 = x->right;
// 执行旋转
x->right = y;
y->left = T2;
// 更新高度
updateHeight(y);
updateHeight(x);
// 返回新的根节点
return x;
}
// 左旋转操作
Node* leftRotate(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 data) {
// 1. 执行标准BST插入
if (node == NULL)
return createNode(data);
if (data < node->data)
node->left = insert(node->left, data);
else if (data > node->data)
node->right = insert(node->right, data);
else // 相等的值不插入(题目说明所有整数不同)
return node;
// 2. 更新当前节点的高度
updateHeight(node);
// 3. 获取平衡因子,检查是否失衡
int balance = getBalance(node);
// 4. 如果失衡,进行旋转调整
// 左左情况:右旋转
if (balance > 1 && data < node->left->data)
return rightRotate(node);
// 右右情况:左旋转
if (balance < -1 && data > node->right->data)
return leftRotate(node);
// 左右情况:先左旋转再右旋转
if (balance > 1 && data > node->left->data) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// 右左情况:先右旋转再左旋转
if (balance < -1 && data < node->right->data) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
// 如果平衡,返回当前节点
return node;
}
int main() {
int n;
scanf("%d", &n);
Node* root = NULL;
for (int i = 0; i < n; i++) {
int num;
scanf("%d", &num);
root = insert(root, num);
}
printf("%d", root->data);
return 0;
}
708

被折叠的 条评论
为什么被折叠?



