- 题目
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the root of the resulting AVL tree in one line.
- 题目大意
本题考查平衡二叉树的建立。 - 解题思路
首先平衡二叉树的定义为:这棵树首先是二叉排序树(BST),并且符合以下的条件
对于每一个节点,他的左子树和右子树的高度差的绝对值不超过1。因此,在建立AVL树时需要不断改变节点的位置来保证AVL树的特性。
1.在二叉树的结构体中增加树的高度这一项,来记录节点对应的树的高度。这时获取节点的高度只需要直接访问节点中的height这一项即可。获得节点的平衡因子只需要左子树的高度减去右子树的高度即可。
2.AVL树的插入,插入后可能会破坏AVL树的特性,这时一共有四种树型
(1)LL型(左子树高度减去右子树高度为1):右旋
(2)LR型(左子树高度减去右子树高度为-1):先左旋左子树,再右旋
(3)RR型(左子树高度减去右子树高度为-1):左旋
(4)RL型(左子树高度减去右子树高度为1):先右旋右子树,再左旋
3.创建AVL树,只需要不断插入节点即可
代码实现:
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct Node{
Node* left, *right; //左右孩子节点
int height, data; //树的高度和节点信息
};
int get_height(Node* root) //获得以root为根节点的树的高度
{
if(root == nullptr)
return 0;
return root->height;
}
int getBelanceFactor(Node* root){ //获得节点平衡因子
return get_height(root->left) - get_height(root->right);
}
void updata_height(Node* root){ //更新节点的高度
root->height = max(get_height(root->left), get_height(root->right)) + 1;
}
void L(Node* &root){ //左旋
Node* temp = root->right;
root->right = temp->left;
temp->left = root;
updata_height(root);
updata_height(temp);
root = temp;
}
void R(Node* &root){ //右旋
Node* temp = root->left;
root->left = temp->right;
temp->right = root;
updata_height(root);
updata_height(temp);
root = temp;
}
void insert_node(Node* &root, int v){ //插入节点
if(root == nullptr){
root = new Node;
root->data = v;
root->left = nullptr;
root->right = nullptr;
root->height = 1;
return;
}
if(v < root->data){
insert_node(root->left, v);
updata_height(root); //更新树高
if(getBelanceFactor(root) == 2) //若平衡因子为2
{
if(getBelanceFactor(root->left) == 1) //LL型{
R(root);
else if(getBelanceFactor(root->left) == -1){ //LR型
L(root->left);
R(root);
}
}
}else{
insert_node(root->right, v);
updata_height(root);
if(getBelanceFactor(root) == -2){
if(getBelanceFactor(root->right) == -1) //RR型
L(root);
else if(getBelanceFactor(root->right)== 1){ //RL型
R(root->right);
L(root);
}
}
}
}
Node* creat_Avl(vector<int> num, int n){
Node* root = nullptr;
for(int i = 0; i < n; i++){
insert_node(root, num[i]);
}
return root;
}
int main()
{
int N;
scanf("%d", &N);
vector<int> num;
for(int i = 0; i < N; i++){
int temp;
scanf("%d", &temp);
num.push_back(temp);
}
Node* root = creat_Avl(num, N);
printf("%d", root->data);
return 0;
}