• PAT甲级——1123 Is It a Complete AVL Tree (完全AVL树的判断)


    嫌排版乱的话可以移步我的CSDN:https://blog.csdn.net/weixin_44385565/article/details/89390802

    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.

    F1.jpgF2.jpg
    F3.jpg F4.jpg

    Now given a sequence of insertions, you are supposed to output the level-order traversal sequence of the resulting AVL tree, and to tell if it is a complete binary tree.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (≤ 20). 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, insert the keys one by one into an initially empty AVL tree. Then first print in a line the level-order traversal sequence of the resulting AVL tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line. Then in the next line, print YES if the tree is complete, or NO if not.

    Sample Input 1:

    5
    88 70 61 63 65
    

    Sample Output 1:

    70 63 88 61 65
    YES
    

    Sample Input 2:

    8
    88 70 61 96 120 90 65 68
    

    Sample Output 2:

    88 65 96 61 70 90 120 68
    NO

    题目大意:给出N个数据,建立AVL树,并判断其是否为完全二叉树。

    思路:题目言简意赅,就两个核心操作:建立AVL树、判断是否为完全二叉树~~

    AVL树的建立过程详见我之前的文章:AVL树(自平衡二叉查找树)

    因为AVL树本身的性质已经保证了左右子树的高度差≤1,所以之后判断完全二叉树主要有两个条件:1、对于每个节点,左子树高度≥右子树高度;2、层序遍历遇到一个节点,它有左孩子但没有右孩子时标记一下,在它之后进入队列的节点都为叶子节点,这棵AVL树为完全二叉树。

      1 #include <iostream>
      2 #include <queue>
      3 #define ElementType int
      4 using namespace std;
      5 typedef struct node *AVLTree;
      6 struct node {
      7     ElementType key;
      8     int Height = 0;
      9     AVLTree left = NULL, right = NULL;
     10 };
     11 bool flag = true;
     12 int Height(AVLTree tree);//求树的高度
     13 ElementType Max(ElementType a, ElementType b);
     14 AVLTree insert(AVLTree tree, ElementType &key);//在AVLTree中插入节点
     15 AVLTree LL_Rotation(AVLTree tree);//LL旋转
     16 AVLTree RR_Rotation(AVLTree tree);//RR旋转
     17 AVLTree LR_Rotation(AVLTree tree);//LR旋转
     18 AVLTree RL_Rotation(AVLTree tree);//RL旋转
     19 void levelTraversal(AVLTree tree);//层序遍历
     20  
     21 int main()
     22 {
     23     int N;
     24     ElementType key;
     25     AVLTree tree = NULL;
     26     scanf("%d", &N);
     27     for (int i = 0; i < N; i++) {
     28         cin >> key;
     29         tree = insert(tree, key);
     30     }
     31     levelTraversal(tree);
     32     if (flag)
     33         printf("YES
    ");
     34     else
     35         printf("NO
    ");
     36  
     37 }
     38  
     39 AVLTree insert(AVLTree tree, ElementType &key) {
     40     if (tree == NULL) {
     41         tree = new node();
     42         tree->key = key;
     43     }
     44     else if (key < tree->key) {
     45         tree->left = insert(tree->left, key);//key小于当前节点的值时继续往其左子树递归地插入
     46         if (Height(tree->left) - Height(tree->right) >= 2) {//左子树与右子树的高度差达到2的时候就要对当前节点进行旋转,这里由于是递归地执行,保证了平衡因子达到2的节点是最接近插入点的
     47             if (key < tree->left->key)
     48                 tree = LL_Rotation(tree);
     49             else
     50                 tree = LR_Rotation(tree);
     51         }
     52     }
     53     else {
     54         tree->right = insert(tree->right, key);
     55         if (Height(tree->right) - Height(tree->left) >= 2) {
     56             if (key > tree->right->key)
     57                 tree = RR_Rotation(tree);
     58             else
     59                 tree = RL_Rotation(tree);
     60         }
     61     }
     62     tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;//当前节点的高度为其最大子树的高度+1
     63     return tree;
     64 }
     65  
     66 AVLTree LR_Rotation(AVLTree tree) {
     67     tree->left = RR_Rotation(tree->left);
     68     return LL_Rotation(tree);
     69 }
     70  
     71 AVLTree RL_Rotation(AVLTree tree) {
     72     tree->right = LL_Rotation(tree->right);
     73     return RR_Rotation(tree);
     74 }
     75  
     76 AVLTree RR_Rotation(AVLTree tree) {
     77     AVLTree tree2 = tree->right;
     78     tree->right = tree2->left;
     79     tree2->left = tree;
     80     tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;
     81     tree2->Height = Max(Height(tree2->right), tree->Height) + 1;
     82     return tree2;
     83 }
     84  
     85 AVLTree LL_Rotation(AVLTree tree) {
     86     AVLTree tree2 = tree->left;
     87     tree->left = tree2->right;
     88     tree2->right = tree;
     89     tree->Height = Max(Height(tree->left), Height(tree->right)) + 1;
     90     tree2->Height = Max(Height(tree->left), tree->Height) + 1;
     91     return tree2;
     92 }
     93  
     94 int Height(AVLTree tree) {
     95     if (tree == NULL)
     96         return 0;
     97     return tree->Height;
     98 }
     99  
    100 ElementType Max(ElementType a, ElementType b) {
    101     return a > b ? a : b;
    102 }
    103  
    104 void levelTraversal(AVLTree tree)
    105 {
    106     bool flag2 = false;
    107     AVLTree t = NULL;
    108     queue <AVLTree> Q;
    109     Q.push(tree);
    110     while (!Q.empty()) {
    111         t = Q.front();
    112         Q.pop();
    113         cout << t->key;
    114         if (flag2 && Height(t) != 1) //高度为1的节点就是叶子节点
    115             flag = false;
    116         if (Height(t->left) < Height(t->right)) //AVL树保证了每个节点的左右子树高度差小于等于1,只要左子树高度小于右子树,这课AVL树就不是完全二叉树
    117             flag = false;
    118         if (t->left != NULL && t->right == NULL) //遇到一个节点,有左孩子但没有右孩子,标记一下,它之后的存入队列中的节点都为叶子节点时这棵AVL树才是完全二叉树
    119             flag2 = true;
    120         if (t->left != NULL)
    121             Q.push(t->left);
    122         if (t->right != NULL)
    123             Q.push(t->right);
    124         if (!Q.empty())
    125             printf(" ");
    126     }
    127     printf("
    ");
    128 }
  • 相关阅读:
    [专项]tcp状态机,为什么3次握手(很好)(done)
    Win7系统如何创建计划任务的小技巧(图文)
    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    Java项目 使用MyEclipse打包生成jar文件方法
    excel插入柱形图和插入置信值
    关于Virtual Box虚拟机里的系统不能启动的解决方法
    html文件的中文乱码问题与在浏览器中的显示 .
    Windows的计划任务
    不能为虚拟电脑 Fedora1 打开一个新任务.
    bat 通过bat脚本来每隔一段时间运行jar包
  • 原文地址:https://www.cnblogs.com/yinhao-ing/p/10736535.html
Copyright © 2020-2023  润新知