• A1066. Root of AVL Tree


    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 ythe root of the resulting AVL tree in one line.

    Sample Input 1:

    5
    88 70 61 96 120
    

    Sample Output 1:

    70
    

    Sample Input 2:

    7
    88 70 61 96 120 90 65
    

    Sample Output 2:

    88

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef struct NODE{
     6     struct NODE* lchild, *rchild;
     7     int key;
     8     int height;
     9 }node;
    10 int getHeight(node* root){
    11     if(root == NULL)
    12         return 0;
    13     else return root->height;
    14 }
    15 void updateHeight(node *root){
    16     root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
    17 }
    18 void L(node* &root){
    19     node* temp = root;
    20     root = root->rchild;
    21     updateHeight(root);
    22     temp->rchild = root->lchild;
    23     root->lchild = temp;
    24     updateHeight(temp);
    25 }
    26 void R(node* &root){
    27     node *temp = root;
    28     root = root->lchild;
    29     updateHeight(root);
    30     temp->lchild = root->rchild;
    31     root->rchild = temp;
    32     updateHeight(temp);
    33 }
    34 void insert(node* &root, int key){
    35     if(root == NULL){   //此处可获得插入节点的信息
    36         node* temp = new node;
    37         temp->lchild = NULL;
    38         temp->rchild = NULL;
    39         temp->key = key;
    40         temp->height = 1;
    41         root = temp;
    42         return;
    43     }
    44     if(key < root->key){   //此处可获得距离插入节点最近得父节点得信息
    45         insert(root->lchild, key);
    46         updateHeight(root);
    47         if(abs(getHeight(root->lchild) - getHeight(root->rchild)) == 2){
    48             if(getHeight(root->lchild->lchild) > getHeight(root->lchild->rchild)){
    49                 R(root);
    50             }else{
    51                 L(root->lchild);
    52                 R(root);
    53             }    
    54         }
    55     }else{
    56         insert(root->rchild, key);
    57         updateHeight(root);
    58         if(abs(getHeight(root->lchild) - getHeight(root->rchild)) == 2){
    59             if(getHeight(root->rchild->rchild) > getHeight(root->rchild->lchild)){
    60                 L(root);
    61             }else{
    62                 R(root->rchild);
    63                 L(root);
    64             }    
    65         }
    66     }
    67 }
    68 int main(){
    69     int N, key;
    70     scanf("%d", &N);
    71     node* root = NULL;
    72     for(int i = 0; i < N; i++){
    73         scanf("%d", &key);
    74         insert(root, key);
    75     }
    76     printf("%d", root->key);
    77     cin >> N;
    78     return 0;
    79 }
    View Code

    总结:

    1、题意:按照题目给出的key的顺序,建立一个平衡二叉搜索树。

    2、二叉搜索树的几个关键地方:

    •  每个节点使用height来记录自己的高度,叶节点高度为1; 
    •   获得某个节点高度的函数,主要是由于在获取平衡因子时,有些树的子树是空的,需要返回0,为避免访问空指针,获取节点高度都要通过该函数而非height字段
    • 更新当前节点的高度,应更新为左右子树的最大高度+1。
    • 左旋与右旋:一定是三步操作而不是两步(不要忘记新的root的原子树)。注意更新节点高度的先后顺序
    • 插入与建树:插入操作基于二叉搜索树的插入。在root = NULL时进行新建节点并插入,在此处可以获得插入节点的信息。而在递归插入语句处,可以获取插入A节点之后距离A节点最近的父节点。因此在递归插入结束后就要对该节点进行更新高度,并在此处更新完之后检查平衡因子,并做LL、LR、RR、RL旋转。

    3、对rootA的左子树做插入,导致rootA的左子树与右子树高度差为2,则对以rootA为根的树旋转。

    4、调试的时候,可以取很少的几个节点,然后画出调试过程中树的形状。

  • 相关阅读:
    快速排序
    推荐!手把手教你使用Git
    「瞻前顾后」写出我心(九十九)
    「减法」写出我心(九十八)
    「焦虑」写出我心(九十七)
    「认知水平」​​​​​​​​写出我心(九十六)
    「成功的事业」写出我心(九十五)
    「爱」​​​​​​写出我心(九十四)
    「赢」​​​​​写出我心(九十三)
    「体面人」​​​​写出我心(九十二)
  • 原文地址:https://www.cnblogs.com/zhuqiwei-blog/p/8544201.html
Copyright © 2020-2023  润新知