PAT 1066 Root of AVL Tree (25)

2017-03-02  本文已影响73人  想学会飞行的阿番

题意

给出N个正整数,将他们依次插入一课初始为空的AVL树上,求插入后的根节点的值

思路

无论是LL,LR,RL,RR型,我们都可以看成把第二大的当作子树的根,最小的为它的左子树,最大的为右子树,这样就可以方便的计算啦(具体过程可以参考邓俊辉的《数据结构》相关内容,强推!!!)

代码


#include<iostream>
#include<cmath>
#include<algorithm>
#include<stack>
#define getFater( a)  (a->father)
#define getHeight(a) (a==NULL?0:a->height)
#define isRoot(a) (a->father == NULL)
using namespace std;

typedef struct NODE
{
    int value;
    NODE * father;
    int height;
    NODE * lchild, *rchild;
}NODE ,*TREE;
TREE t;
NODE * opt34(NODE *a, NODE* b, NODE *c, NODE *t1, NODE* t2, NODE*t3, NODE*t4);


//判断是不是父节点的左子树
bool isLchild(NODE *a) { return (!isRoot(a) && (a->father->lchild == a)); }
//获取决定node的高度的那个子节点
NODE * getTallerChild(NODE * node) { return (((getHeight(node->lchild)) > (getHeight(node->rchild))) ? (node->lchild) : (node->rchild)); }


//更新高度
void updateHeight(NODE * node)
{
    node->height =  max(getHeight(node->lchild), getHeight(node->rchild))+1;
    
}

//插入
NODE * insert(NODE * &node,NODE * &father,int a)
{
    if (node == NULL)
    {
        node = new NODE;
        node->lchild = node->rchild = NULL;
        if (father != node)
            node->father = father;
        else
            node->father = NULL;
        node->height = 1;
        node->value = a;
        return node;
    }
    else
    {
        if (node->value < a)
             return insert(node->rchild, node, a);
        else
            return insert(node->lchild,node,a);
    }
    
}

//旋转
NODE * rotateAT(NODE * a)
{
    NODE *b = a->father;
    NODE *c = b->father;
    if (isLchild(a))
    {
        if (isLchild(b))
        {
            b->father = c->father;
            return opt34(a, b, c, a->lchild, a->rchild, b->rchild, c->rchild);
        }
        else
        {
            a->father = c->father;
            return opt34(c, a, b, c->lchild, a->lchild, a->rchild, b->rchild);
        }
    }
    else
    {
        if (!(isLchild(b)))
        {
            b->father = c->father;
            return opt34(c, b, a, c->lchild, b->lchild, a->lchild, a->rchild);
        }
        else
        {
            a->father = c->father;
            return opt34(b, a, c, b->lchild, a->lchild, a->rchild, c->rchild);
        }
    }
}

//具体操作3+4
NODE * opt34(NODE *a,NODE* b,NODE *c,NODE *t1,NODE* t2,NODE*t3,NODE*t4)
{
    a->lchild = t1; if (t1 != NULL) t1->father = a;
    a->rchild = t2; if (t2 != NULL) t2->father = a;
    updateHeight(a);
    c->lchild = t3; if (t3 != NULL) t3->father = c;
    c->rchild = t4; if (t4 != NULL) t4->father = c;
    updateHeight(c);
    b->lchild = a; a->father = b;
    b->rchild = c; c->father = b;
    updateHeight(b);
    return b;
}

bool AvlBalanced(NODE * g)
{
    int height;
    height = getHeight(g->lchild)- getHeight(g->rchild);
    return (-2 < height)&&(height < 2);
}


//插入过程
void insertAVL(int x)
{
    NODE *temp = insert(t,t,x);
    for (NODE * g = getFater(temp);g!=NULL;g = getFater(g))
    {
               /*
              原来代码这么写,然后一直只有最后一个测试点过了,并且出现段错误
              (isRoot(g) ? t : (isLchild(g) ? (g)->father->lchild : (g)->father->rchild)) =               rotateAT(getTallerChild(getTallerChild(g)));
              然后改为下文这么一串就对了
              */

        if (!AvlBalanced(g))//情愿代码写长一点,呜呜呜
        {
            if (g == t)
            {
                t = rotateAT(getTallerChild(getTallerChild(g)));
            }
            else
            {
                if (g == g->father->lchild)
                {
                    g->father->lchild = rotateAT(getTallerChild(getTallerChild(g)));
                }
                else
                    g->father->rchild = rotateAT(getTallerChild(getTallerChild(g)));
            }
            
            break;
        }
        else
            updateHeight(g);
    }
    return ;
}

int main()
{
    t = NULL;
    int n;
    int value;
    int ore[25];
    scanf("%d",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d",&value);
        insertAVL(value);
    }
    printf("%d\n",t->value);
    system("pause");
    return 0;
}


后记

这一题的通过率超级高,然而我一开始还是只对了一个测试点,并且测试点4和5出现段错误,现在还是不知道为什么,希望能够灵光一现,然后解决,嘻嘻

上一篇 下一篇

猜你喜欢

热点阅读