平衡二叉树 sdut oj 3374

此处看题

怎么说呢,我刚开始对于这个平衡树简直无计可施,但是学长讲了之后,问了几个问题,感觉有问题主要是以下几个地方:

  1. 树高怎么记录(其实也不算什么大问题)
  2. 旋转的时候,结点以及结点的孩子是怎么操作的
  3. 建树的时候对于是否失衡的判断

下面贴代码
PS:本人外语是小语种,自定义函数基本是汉语拼音的缩写,比较尴尬

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node
{
    int data;
    int h;
    struct node *l, *r;
};

int geth(struct node *root)  //获取结点的树高
{
    if(root)
        return root->h;
    else
        return -1;
}

struct node* ll(struct node *root)  //左左结构旋转,即造成失衡的结点在失衡结点的左子树的左子树上
{
    struct node *p;
    p = root->l;
    root->l = p->r;
    p->r = root;
    root->h = geth(root->l) > geth(root->r) ? geth(root->l) + 1 : geth(root->r) + 1;
    p->h = geth(p->l) > geth(p->r) ? geth(p->l) + 1 : geth(p->r) + 1;
    return p;
};

struct node* rr(struct node *root)  //右右结构旋转,与左左同理
{
    struct node *p;
    p = root->r;
    root->r = p->l;
    p->l = root;
    root->h = geth(root->l) > geth(root->r) ? geth(root->l) + 1 : geth(root->r) + 1;
    p->h = geth(p->l) > geth(p->r) ? geth(p->l) + 1 : geth(p->r) + 1;
    return p;
};

struct node* lr(struct node *root)  //左右结构旋转,在失衡结点的左结点进行右右旋转,然后在失衡的结点进行左左旋转
{
    root->l = rr(root->l);
    return ll(root);
};

struct node* rl(struct node *root)//右左结构旋转,在失衡结点的右结点进行左左旋转,然后在失衡的结点进行右右旋转
{
    root->r = ll(root->r);
    return rr(root);
};

struct node* js(struct node *root, int a)   //建立平衡二叉树
{
    if(root == NULL)  //如果结点为空,则分配空间,再对其中的值进行初始化
    {
        root = (struct node*)malloc(sizeof(struct node));
        root->data = a;
        root->h = 0;
        root->l = NULL;
        root->r = NULL;
    }
    else  //如果不空
    {
        if(a > root->data)  //如果a大于当前结点的值
        {
            root->r = js(root->r, a);  //进入右子树
            if(geth(root->l) - geth(root->r) == -2)  //如果右子树过高(平衡被破坏)
            {
                if(a > root->r->data)  //判断失衡结构,进行相应的旋转
                {
                    root = rr(root);
                }
                else
                {
                    root = rl(root);
                }
            }
        }
        else
        {
            root->l = js(root->l, a);  //进入左子树
            if(geth(root->l) - geth(root->r) == 2)  //如果左子树过高(平衡被破坏)
            {
                if(a > root->l->data)  //判断失衡结构,进行相应旋转
                {
                    root = lr(root);
                }
                else
                {
                    root = ll(root);
                }
            }
        }
    }
    root->h = geth(root->l) > geth(root->r) ? geth(root->l) + 1 : geth(root->r) + 1;  //更新结点树高
    return root;  //返回结点
};

int main()
{
    int n, m, i;
    struct node *root = NULL;
    scanf("%d", &n);
    for(i = 0;i < n;i++)
    {
        scanf("%d", &m);
        root = js(root, m);  //建立树
    }
    printf("%d\n", root->data);  //输出树根的值
    return 0;
}

对于LL型,RR型,LR型,RL型,由于能力有限,建议参考这篇文章

猜你喜欢

转载自blog.csdn.net/luluxiu_1999/article/details/81710889