PAT A1066 Root of AVL Tree (25 分)

41 篇文章 0 订阅
6 篇文章 0 订阅
  • 题目

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值