• PAT.1066 Root of AVL Tree(平衡树模板题)


    1066 Root of AVL Tree (25分)

     

    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 (≤) 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.

    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

    平衡树模板题。

    口诀:
    先插入,后旋转。
    插入记得更新高度。
    旋转儿子父亲交换。
    儿子的儿子也要管。
    直线型儿子父亲交换。
    S型先旋S下部变为直然后再旋直。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 using namespace std;
     5 
     6 struct Tree {
     7     int data, high;
     8     Tree *l, *r;
     9 } *root;
    10 
    11 int max(int a, int b) {
    12     return a > b ? a : b;
    13 }
    14 
    15 typedef Tree * ptree;
    16 
    17 int get_high(ptree root) {
    18     if(root == NULL) return 0;
    19     else return root -> high;
    20 }
    21 
    22 void update_high(ptree root) {
    23     root -> high = max(get_high(root -> l), get_high(root -> r)) + 1;
    24 }
    25 
    26 int balance_factor(ptree root) {
    27     return get_high(root -> l) - get_high(root -> r);
    28 }
    29 
    30 void left_rotary(ptree &root) {
    31     ptree temp = root -> r;
    32     root -> r = temp -> l;
    33     temp -> l = root;
    34     update_high(root);
    35     update_high(temp);
    36     root = temp;
    37 }
    38 
    39 //右旋:root做root的左儿子的右儿子,那么如果root的左儿子原本就有右儿子,需要把他变为root的左儿子。然后再将root变为他的左儿子的右儿子,记得更新这两颗子树的高度,还要将这两颗子树的
    40 //根节点变为root的左儿子
    41 
    42 void right_rotary(ptree &root) {
    43     ptree temp = root -> l;
    44     root -> l = temp -> r;
    45     temp -> r = root;
    46     update_high(root);
    47     update_high(temp);
    48     root = temp;
    49 }
    50 
    51 void avl_insert(ptree &root, int num) {
    52     if(root == NULL) {//叶子节点,设定叶子节点高度为1
    53         root = new Tree;
    54         root -> data = num;
    55         root -> high = 1;
    56         root -> l = root -> r = NULL;
    57     } else {
    58         if(num < root -> data) {
    59             avl_insert(root -> l, num);
    60             update_high(root);//在root的子树中插入新元素需要重新调整这个树的高度
    61             if(balance_factor(root) == 2) {//在root的子树中插入新元素后需要检查树是否平衡
    62                 if(balance_factor(root -> l) == 1) {//如果root的左子树高度为1,则说明需要右旋
    63                     right_rotary(root);
    64                 } else if(balance_factor(root -> l) == -1) {//如果root的左子树比右子树低,则需要先左旋再右旋
    65                     left_rotary(root -> l);
    66                     right_rotary(root);
    67                 } 
    68             }
    69         } else {
    70             avl_insert(root -> r, num);
    71             update_high(root);
    72             if(balance_factor(root) == -2) {//如果是插入到root的右子树的话,那么root的右子树比左子树高2才需要调整
    73                 if(balance_factor(root -> r) == -1) {
    74                     left_rotary(root);
    75                 } else if(balance_factor(root -> r) == 1) {
    76                     right_rotary(root -> r);
    77                     left_rotary(root);
    78                 }
    79             }
    80         }
    81     }
    82 }
    83 
    84 int main() {
    85     int n, num;
    86     scanf("%d", &n);
    87     while(n --) {
    88         scanf("%d", &num);
    89         avl_insert(root, num);
    90     }
    91     printf("%d
    ", root -> data);
    92     return 0;
    93 }

      

  • 相关阅读:
    Intellij IDEA + Jrebel
    WebConfig配置详解大全
    .Net 获取前端传递的数据
    js 格式验证大全
    EasyUI DataGrid 时间格式化、字符串长度截取
    SQL取某个字符串最后一次出现的位置后面的字符串方法
    公民身份号码校验码算法(C#版)
    组织机构代码校验码生成算法(C#版)
    MySQL实现根据当前ID读取上一条和下一条记录
    js jquery.pagination.js分页
  • 原文地址:https://www.cnblogs.com/bianjunting/p/13052478.html
Copyright © 2020-2023  润新知