PAT 1066 Root of AVL Tree

题意:
根据输入的数值,形成平衡二叉树(AVL),然后输出根节点的值。
解法:
老老实实的实现AVL树:
四种不平衡情况:
1、插入到A的左子树的左子树上,右旋A,
2、插入到A的左子树的右子树上,左旋A的左子树,再右旋A。
3、插入到A的右子树的左子树上,右旋A的右子树,再左旋A,
4、插入到A的右子树的右子树上,左旋A。
反思:
这一题还是写不出来,对于AVL树的掌握还是不到位,拿出大学课本,用上面的代码实现一下。对比了一下别人写的代码,课本上的代码比较难理解一点。每次更新往上更新平衡因子,判断树是否变高了,是的话就根据当前是左或右子树,再根据平衡因子判断是否存在不平衡,有则调整,变化完后更新平衡因子,从下往上做调整。原
(用时:1.58:00.67)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<map>
#include<stack>
//#include<bits/stdc++.h>
using namespace std;
struct BiNode {
    int data;
    int bf;
    BiNode *Left,*Right;
};
void RRoate(BiNode* &p)
{
    BiNode* lChild= p->Left;
    p->Left = lChild->Right;
    lChild->Right = p;
    p = lChild;
}

void LRoate(BiNode* &p)
{
    BiNode* rChild= p->Right;
    p->Right = rChild->Left;
    rChild->Left = p;
    p = rChild;
}

void LeftBalance(BiNode* &p)
{
    BiNode* lChild = p->Left;
    switch(lChild->bf) {
    case 1:
        p->bf = lChild->bf = 0;
        RRoate(p);
        break;
    case -1:
        BiNode *lrChild = lChild->Right;
        switch(lrChild->bf) {
        case 1:
            p->bf = -1;
            lChild->bf = 1;
            break;
        case 0:
            p->bf = lChild->bf = 0;
            break;
        case -1:
            p->bf = 0;
            lChild->bf = 1;
            break;
        }
        lrChild->bf = 0;
        LRoate(p->Left);
        RRoate(p);
        break;
    }
}

void RightBalance(BiNode* &p)
{
    BiNode* rChild = p->Right;
    switch(rChild->bf) {
    case -1:
        p->bf = rChild->bf = 0;
        LRoate(p);
        break;
    case 1:
        BiNode *rlChild = rChild->Left;
        switch(rlChild->bf) {
        case 1:
            p->bf = 0;
            rChild->bf = -1;
            break;
        case 0:
            p->bf = rChild->bf = 0;
            break;
        case -1:
            p->bf = 1;
            rChild->bf = 0;
            break;
        }
        rlChild->bf = 0;
        RRoate(p->Right);
        LRoate(p);
        break;
    }
}

void getTree(BiNode* &root,int value,bool &taller)
{
    if(root==NULL) {
        root  =   (BiNode*)malloc(sizeof(BiNode));
        root->Left = root->Right = NULL;
        root->bf = 0;
        root->data = value;
        taller = true;
    } else {
        if(root->data>=value) {
            getTree(root->Left,value,taller);
            if(taller) {
                switch(root->bf) {
                case 1:
                    LeftBalance(root);
                    taller = false;
                    break;
                case 0:
                    root->bf = 1;
                    taller= true;
                    break;
                case -1:
                    root->bf = 0;
                    taller= false;
                    break;
                }

            }
        } else {
            getTree(root->Right,value,taller);
            if(taller){
            switch(root->bf) {
            case 1:
                root->bf = 0;
                taller= false;
                break;
            case 0:
                root->bf = -1;
                taller= true;
                break;
            case -1:
                RightBalance(root);
                taller= false;
                break;
            }
            }
        }
    }

}

int main()
{
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0; i<n; i++) {
        scanf("%d",&a[i]);
    }
    BiNode *root =NULL;
    bool taller = false;
    for(int i=0; i<n; i++) {
        taller = false;
        getTree(root,a[i],taller);
    }
    printf("%d\n",root->data);

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值