A1123 Is It a Complete AVL Tree (30 分| AVL树| 完全二叉树| 层次遍历,附详细注释,逻辑分析)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_24452475/article/details/100587064

写在前面

  • 思路分析
    • 判断是不是完全二叉树
      • 出现1个孩⼦为空的结点之后是否还会出现孩子结点不为空的结点,如果出现就不是完全⼆叉树
    • AVL树共四种情况,发现树不平衡的结点记为A结点, A发现树不不平衡的情况有四种:
  • 知识盲点,学习ing
    • 难度较大,代码量较大

测试用例

  • input:
    5
    88 70 61 63 65
    
    output:
    70 63 88 61 65
    YES
    
    input:
    8
    88 70 61 96 120 90 65 68
    
    output:
    88 65 96 61 70 90 120 68
    NO
    

ac代码

  • #include <iostream>
    #include <vector>
    #include <queue>
    
    using namespace std;
    struct node
    {
        int val;
        struct node *left, *right;
    };
    
    node* leftRotate(node *tree)
    {
        node *tmp = tree->right;
        tree->right = tmp->left;
        tmp->left = tree;
    
        return tmp;
    }
    
    node* rightRotate(node *tree)
    {
        node *tmp = tree->left;
        tree->left = tmp->right;
        tmp->right = tree;
        return tmp;
    }
    node* leftRightRotate(node *tree)
    {
        tree->left = leftRotate(tree->left);
        return rightRotate(tree);
    }
    node* rightLeftRotate(node *tree)
    {
        tree->right = rightRotate(tree->right);
        return leftRotate(tree);
    }
    int getHeight(node *tree)
    {
        if(tree == NULL) return 0;
        int l = getHeight(tree->left);
        int r = getHeight(tree->right);
    
        return max(l, r)+1;
    }
    node* inserts(node *tree, int val)
    {
        if(tree == NULL)
        {
            tree = new node();
            tree->val = val;
        }
        else if(tree->val > val)
        {
            tree->left = inserts(tree->left, val);
            int l = getHeight(tree->left), r = getHeight(tree->right);
    
            if(l-r>=2)
            {
                if(val < tree->left->val)
                    tree = rightRotate(tree);
                else
                    tree = leftRightRotate(tree);
            }
        }
        else
        {
            tree->right = inserts(tree->right, val);
            int l=getHeight(tree->left), r = getHeight(tree->right);
            if(r-l >= 2)
            {
                if(val>tree->right->val)
                    tree = leftRotate(tree);
                else
                    tree = rightLeftRotate(tree);
            }
        }
    
        return tree;
    }
    int isComplete = 1, after = 0;
    vector<int> levelOrder(node *tree)
    {
        vector<int> v;
        queue<node *> queues;
        queues.push(tree);
    
        while(!queues.empty())
        {
            node *tmp = queues.front();
            queues.pop();
            v.push_back(tmp->val);
            if(tmp->left != NULL)
            {
                if(after) isComplete = 0;
                queues.push(tmp->left);
            }
            else
                after = 1;
            if(tmp->right != NULL)
            {
                if(after) isComplete = 0;
                queues.push(tmp->right);
            }
            else
                after = 1;
        }
    
        return v;
    }
    
    int main()
    {
        int n, tmp;
        scanf("%d", &n);
    
        node *tree = NULL;
        for(int i=0; i<n; i++)
        {
            scanf("%d", &tmp);
            tree = inserts(tree, tmp);
        }
        vector<int> v = levelOrder(tree);
        for(int i=0; i<v.size(); i++)
        {
            if(i!=0) printf(" ");
            printf("%d", v[i]);
        }
        printf("\n%s", isComplete ? "YES" : "NO");
    
        return 0;
    }
    

知识点小结

  • AVL树知识点
    • 左右子树都是AVL树
    • AVL树中任何节点的两个子树的高度最大差别为1
    • 左子树和右子树高度之差(简称平衡因子)的绝对值不超过1(-1、0、1)
    • 查找
    • 在这里插入图片描述
    • 插入
    • 在这里插入图片描述
    • 左旋
    • 在这里插入图片描述
    • 右旋
    • 在这里插入图片描述
    • 情况汇总
    • 在这里插入图片描述
  • 判断是否是完全二叉树
    • 如果树为空,则直接返回错
    • 如果树不为空:层序遍历二叉树
      • 如果1个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列
        • 如果遇到1个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树
        • 如果遇到1个结点,左孩子不为空,右孩子为空;或左右孩子都为空;则该节点之后队列中的结点都为叶子节点;该树才是完全二叉树,否则不是完全二叉树
  • 二叉树层次遍历
    • 构建1个队列 依次访问二叉树的头结点
    • 判断头结点不为空然后进入
      • 首先将根节点入队 从根节点判断左右子节点
      • 然后出队队头元素
      • 队列的作用就是将二叉树按照 根 左 右的顺序接收然后出队操作
      • 最终队列为空的时候 跳出循环 达到层次遍历的目的
    • 在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_24452475/article/details/100587064