1123. Is It a Complete AVL Tree(AVL树旋转、判断完全二叉树)

Is It a Complete AVL Tree (30)
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.
《1123. Is It a Complete AVL Tree(AVL树旋转、判断完全二叉树)》
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

题目说明:根据AVL树的插入规则,输入一段数字,根据输入的数字构建 AVL树。然后,根据层序遍历输出对应的数字,之后再判断这棵AVL树是否是完全二叉树。
分析要点:这道题首先要解决的问题是引起AVL树不平衡的插入的四种情况(设结点A为不平衡结点):
1.新插入的结点在A的左子树的左子树。
2.新插入的结点在A的左子树的右子树。
3.新插入的结点在A的右子树的左子树。
4.新插入的结点在A的右子树的右子树。
如何判断出现不平衡呢?其实也非常简单。对于一个结点来说,一个结点的左子树高度和右子树高度相差>=2,说明出现了不平衡。需要进行旋转。
旋转的规则也简单:情况1.右旋。2.对A的左子树进行左旋(接着会出现情况1),接着对A右旋。3.对A的右子树进行右旋(接着会出现情况4),接着去A左旋。4.左旋。
最后,如何判断是否为完全二叉树。这个也简单,回想完全二叉树的定义:叶结点与叶结点的高度差不能超过2。并且,缺的部分必须在右边。所以,只要从左到右的层序遍历,一旦出现了叶结点,就不能再出现非叶结点了。

如何左旋和右旋呢?我觉得代码更清楚,代码如下:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;

int isComplete=1;int after=0;


struct node
{
    int val;
    node* left;
    node* right;
    node(int a):val(a),left(NULL),right(NULL){}
};

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);
    tree=rightrotate(tree);
    return tree;
}

node* rightLeftrotate(node* tree)
{
    tree->right=rightrotate(tree->right);
    tree=leftrotate(tree);
    return tree;
}

int getHeight(node* tree)
{
    if(tree==NULL)
        return 0;
    else
    {
        int l=getHeight(tree->left);
        int r=getHeight(tree->right);
        return l>r? l+1:r+1;
    }
}

node* insert(node* root,int val)
{
    if(root==NULL)
    {
        node* tree=new node(val);
        return tree;
    }
    else
    {
        if(val>(root->val))
        {
            root->right=insert(root->right,val);
            int l=getHeight(root->left);
            int r=getHeight(root->right);
            if(r-l>=2)
            {
                if(val<(root->right->val))
                    root=rightLeftrotate(root);
                else
                    root=leftrotate(root);
            }
        }
        else
        {
            root->left=insert(root->left,val);
            int l=getHeight(root->left);
            int r=getHeight(root->right);
            if(l-r>=2)
            {
                if(val>(root->left->val))
                    root=leftRightrotate(root);
                else
                    root=rightrotate(root);
            }
        }
    }
    return root;
}


vector<int> printtree(node* root)
{
    vector<int> res;
    queue<node*> q;
    q.push(root);
    while(!q.empty())
    {
        node* tmp=q.front();
        q.pop();
        res.push_back(tmp->val);
        //满二叉树的定义是一旦一个结点的左儿子有结点,后面的所有结点必须全为叶子结点
        //所以出现左边没结点,右边有结点也不为完全树
        //故一旦从左边开始出现叶子结点,后面都必须是叶子结点
        if(tmp->left!=NULL)
        {
            if(after)
            {
                isComplete=0;
            }
            q.push(tmp->left);
        }
        else
        {
            after=1;
        }
        if(tmp->right!=NULL)
        {
            if(after)
            {
                isComplete=0;
            }
            q.push(tmp->right);
        }
        else
        {
            after=1;
        }
    }
    return res;
}



int main()
{
    int k;
    scanf("%d",&k);
    node* tree;
    for(int i=0;i<k;++i)
    {
        int tmp;
        scanf("%d",&tmp);
        tree=insert(tree,tmp);
    }
    vector<int> res=printtree(tree);
    for(int i=0;i<res.size();++i)
    {
        if(i==0)
            printf("%d",res[i]);
        else
            printf(" %d",res[i]);
    }
    printf("\n");
    if(isComplete)
        printf("YES");
    else
        printf("NO");
    return 0;
}
    原文作者:AVL树
    原文地址: https://blog.csdn.net/github_33873969/article/details/79487199
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞