1123 Is It a Complete AVL Tree

这一题是根据输入,生成一棵二叉平衡搜索(AVL)树,然后输出其层次遍历,判断是否是完全二叉树,是输出YES,不是输出NO。
AVL树虽然知道,但是从来没写过,难点在于如何进行平衡,进行左旋右旋,有四种情况:
1、在左子树的左子树上插入导致不平衡,进行右旋操作。
2、在左子树的右子树上插入导致不平衡,进行先左旋后右旋操作。
3、在右子树的右子树上插入导致不平衡,进行左旋操作。
4、在右子树的左子树上插入导致不平凡,进行先右旋后左旋操作。
想了半天不知道怎么写,就拿出大学的书根据上面的代码敲了一遍,以为可以出来,结果有问题,改了老半天,主要还是对指针的使用不是很熟练。
看了一下别人的代码,是根据求左右子树的高度,然后求出当前的平衡因子,不平衡再根据条件进行平衡。书上的是直接根据当前的平衡因子出发判断,不好理解,需要动手画一画。
对于AVL树的操作,个人理解不是很到位,有时间还要好好研究研究。
判断是不是完全二叉树,可以在层次变量的时候判断,统计压入队列中的个数,当遇到节点没有子节点时,判断是否与n相同,即可知道是不是二叉树。
(用时:4:14:18.91)

#include <bits/stdc++.h>
using namespace std;
struct BTNode {
    int value;
    int bf;
    BTNode *left,*right;
};

BTNode*  RRoate(struct BTNode* p)
{
    BTNode *lc = p->left;
    p->left = lc->right;
    lc->right = p;
    p = lc;
    return p;
}

BTNode* LRoate(struct BTNode* p)
{
    BTNode *rc = p->right;
    p->right = rc->left;
    rc->left = p;
    p = rc;
    return p;
}
//左平衡
BTNode* leftBalance(BTNode* p)
{
    BTNode *lc = p->left;
    //为插入前的节点上平衡因子
    switch(lc->bf) {
    case 1:
        p->bf = lc->bf=0;
        p=RRoate(p);
        break;
    case -1://插入到左子树上的右子树节点
        BTNode *rd = lc->right;
        switch(rd->bf) {
        case 1:
            p->bf = -1;
            lc->bf = 0;
            break;
        case 0:
            p->bf = lc->bf = 0;
            break;
        case -1:
            p->bf = 0;
            lc->bf = 1;
            break;
        }
        rd->bf = 0;
         p->left=LRoate(lc);
         p=RRoate(p);
        break;
    }
    return p;
}
//右平衡
BTNode* RightBalance(BTNode* p)
{
 BTNode *rc = p->right;
    switch(rc->bf) {
    case -1:
        p->bf = rc->bf=0;
       p=LRoate(p);
        break;
    case 1:
        BTNode *ld = rc->left;
        switch(ld->bf) {
        case 1:
            p->bf = 0;
            rc->bf = -1;
            break;
        case 0:
            p->bf = rc->bf = 0;
            break;
        case -1:
            p->bf = 1;
            rc->bf = 0;
            break;
        }
        ld->bf = 0;
       p->right=RRoate(rc);
       p=LRoate(p);
        break;
    }
    return p;
}

BTNode* InsertAVL(BTNode* root,int data,bool &taller)
{
    if(!root) {
        root = (BTNode*)malloc(sizeof(BTNode));
        root->left = root->right = NULL;
         root->value = data;
        root->bf = 0;
        taller= true;
    } else {
        if(data <= root->value ) {
       root->left = InsertAVL(root->left,data,taller);
            if(taller)//树变高了
                switch(root->bf) {
                case 1://左子树比右子树高
                    root=leftBalance(root);
                    taller = false;
                    break;
                case 0:
                    root->bf = 1;
                    taller= true;
                    break;
                case -1://右子树比左子树高
                    root->bf = 0;
                    taller = false;
                    break;
                }
        } else {
         root->right = InsertAVL(root->right,data,taller);
            if(taller)//树变高了
                switch(root->bf) {
                case 1:
                    root->bf = 0;
                    taller= false;
                    break;
                case 0:
                    root->bf = -1;
                    taller= true;
                    break;
                case -1:
                   root= RightBalance(root);
                    taller= false;
                    break;
                }
        }
    }
    return root;
}
int main()
{
    int n;
    scanf("%d",&n);
    int data[n];
    for(int i=0;i<n;i++){
        scanf("%d",&data[i]);
    }
    BTNode *root= NULL;
    bool taller = false;

    for(int i=0;i<n;i++){
            taller = false;
      root=InsertAVL(root,data[i],taller);

    }

    bool first = 1;
    bool isCompleted = true;
    queue<BTNode*> que;
        que.push(root);
            int treeNum =1;
    while(!que.empty()){
        BTNode *p = que.front();
        que.pop();

            if(first){
                printf("%d",p->value);
                first = 0;
            }
            else{
                printf(" %d",p->value);
            }
            if(p->left!=NULL){
            que.push(p->left);
            treeNum++;
            }
            else{
                if(treeNum!=n){
                    isCompleted = false;
                }
            }
            if(p->right!=NULL){
                que.push(p->right);
                 treeNum++;
            }
            else{
                   if(treeNum!=n){
                    isCompleted = false;
                }
            }

    }

    printf("\n");
 if(isCompleted){
    printf("YES\n");
 }
 else{
    printf("NO\n");
 }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值