PAT(A)-1123. Is It a Complete AVL Tree (30)(AVL+bfs)

记录一个菜逼的成长。。

题目链接

题目大意:
给你n个值,建一棵AVLtree,输出这棵树的层序遍历,并问这棵树是否是完全二叉树

其实只要搞清楚LL旋转就可以推出其余三种旋转了。
我觉得代码说的还是很清楚的,看具体的代码吧。
还是不懂的话可以参考这里
不过链接里代码有两处有点问题,认真的看的话看的出来的。

#include <bits/stdc++.h>
using namespace std;
#define ALL(v) (v).begin(),(v).end()
#define cl(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int maxn = 2000000 + 10;
int vis[maxn];
struct Node{
    int h,v;
    Node *l,*r;
};
int cal_hei(Node* T)
{
    if(T == NULL)return 0;
    return T -> h;
}
Node* singleLeftRotate(Node *T)
{
    Node *tmp = T -> r;
    T -> r = tmp -> l;
    tmp -> l = T;
    T -> h = max(cal_hei(T->l),cal_hei(T->r)) + 1;
    tmp -> h = max(cal_hei(tmp->l),cal_hei(tmp->r)) + 1;
    return tmp;
}
Node* singleRightRotate(Node *T)
{
    Node *tmp = T -> l;
    T -> l = tmp -> r;
    tmp -> r = T;
    T -> h = max(cal_hei(T->l),cal_hei(T->r)) + 1;
    tmp -> h = max(cal_hei(tmp->l),cal_hei(tmp->r)) + 1;
    return tmp;
}
Node *leftRightRotate(Node *T)
{
    T -> l = singleLeftRotate(T->l);
    return singleRightRotate(T);
}
Node *rightLeftRotate(Node *T)
{
    T -> r = singleRightRotate(T -> r);
    return singleLeftRotate(T);
}
Node* Insert(Node *&T,int key)
{
    if(T == NULL){
        T = new Node;
        T -> l = T -> r = NULL;
        T -> v = key;
        T -> h = 1;
    }
    else if(key > T->v){
        T -> r = Insert(T->r,key);
        int dif_hei = cal_hei(T->r) - cal_hei(T->l);
        if(dif_hei == 2){
            if(key > T->r->v){
                T = singleLeftRotate(T);
            }
            else {
                T = rightLeftRotate(T);
            }
        }
    }
    else if(key < T->v){
        T -> l = Insert(T->l,key);
        int dif_hei = cal_hei(T->l) - cal_hei(T->r);
        if(dif_hei == 2){
            if(key < T->l->v){
                T = singleRightRotate(T);
            }
            else {
                T = leftRightRotate(T);
            }
        }
    }
    else {}
    T->h = max(cal_hei(T->l),cal_hei(T->r)) + 1;
    return T;
}
void bfs(Node* T)
{
    queue<pair<Node*,int> >q;
    q.push(mp(T,1));
    int flag = 1;
    while(!q.empty()){
        pair<Node*,int> ff = q.front();q.pop();
        Node* f = ff.fi;
        vis[ff.se] = 1;
        if(flag){printf("%d",f->v);flag = 0;}
        else printf(" %d",f->v);
        if(f->l != NULL)q.push(mp(f->l,ff.se<<1));
        if(f->r != NULL)q.push(mp(f->r,ff.se<<1|1));
    }
    puts("");
}
void check(int n)
{
    for( int i = 1; i <= n; i++ ){
        if(!vis[i]){puts("NO");return ;}
    }
    puts("YES");
}
int main()
{
    Node *tree = NULL;
    int n;
    while(~scanf("%d",&n)){
        for( int i = 0; i < n; i++ ){
            int x;scanf("%d",&x);
            tree = Insert(tree,x);
        }
        bfs(tree);
        check(n);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值