浙大版《数据结构(第2版)》题目集-练习4.2 平衡二叉树的根 (25分)

将给定的一系列数字插入初始为空的AVL树,请你输出最后生成的AVL树的根结点的值。

输入格式:

输入的第一行给出一个正整数N(≤20),随后一行给出N个不同的整数,其间以空格分隔。

输出格式:

在一行中输出顺序插入上述整数到一棵初始为空的AVL树后,该树的根结点的值。

输入样例1:

5
88 70 61 96 120

输出样例1:

70

输入样例2:

7
88 70 61 96 120 90 65

输出样例2:

88

参考代码:

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

typedef struct AVLNode *AVLTree;
struct AVLNode{
    int data;
    AVLTree left;
    AVLTree right;
    int height; //树高
};

/*函数声明*/
int max(int a,int b);
int getHeight(AVLTree T);       //求树高
AVLTree llRotation(AVLTree A);  //LL旋转
AVLTree rrRotation(AVLTree A);  //RR旋转
AVLTree lrRotation(AVLTree A);  //LR旋转
AVLTree rlRotation(AVLTree A);  //RL旋转
AVLTree Insert(AVLTree T,int x);//将x插入AVL树中,并返回调整后的树

int main()
{
    int n,x;
    scanf("%d",&n);
    AVLTree T=NULL;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        T=Insert(T,x);
    }
    printf("%d",T->data);
    return 0;
}

int max(int a,int b)
{
    return a>b?a:b;
}

int getHeight(AVLTree T)
{
    int hl,hr,maxh;
    if(T)
    {
        hl=getHeight(T->left);
        hr=getHeight(T->right);
        maxh=max(hl,hr);
        return (maxh+1);
    }
    else
    {
        return 0;
    }
}

AVLTree llRotation(AVLTree A)
{
    AVLTree B=A->left;
    A->left=B->right;
    B->right=A;
    A->height=max(getHeight(A->left),getHeight(A->right))+1;
    B->height=max(getHeight(B->left),A->height)+1;
    return B;
}

AVLTree rrRotation(AVLTree A)
{
    AVLTree B=A->right;
    A->right=B->left;
    B->left=A;
    A->height=max(getHeight(A->left),getHeight(A->right))+1;
    B->height=max(A->left,getHeight(B->right))+1;
    return B;
}

AVLTree lrRotation(AVLTree A)
{
    A->left=rrRotation(A->left);
    return llRotation(A);
}


AVLTree rlRotation(AVLTree A)
{
    A->right=llRotation(A->right);
    return rrRotation(A);
}

/*将X插入AVL树T中,并且返回调整后的AVL树*/ 
AVLTree Insert(AVLTree T,int x)
{
    if(!T)//若插入空树,则新建包含一个结点的树
    {
        T=(AVLTree)malloc(sizeof(struct AVLNode));
        T->data=x;
        T->height=0;
        T->left=T->right=NULL;
    }
    else if(x<T->data)//插入T的左子树
    {
        T->left=Insert(T->left,x);//如果需要左旋
        if(getHeight(T->left)-getHeight(T->right)==2)//如果需要左旋
        {
            if(x<T->left->data)
            {
                T=llRotation(T);//LL旋转
            }
            else
            {
                T=lrRotation(T);//LR旋转
            }
        }
    }
    else if(x>T->data)//插入T的右子树
    {
        T->right=Insert(T->right,x);
        if(getHeight(T->left)-getHeight(T->right)==-2)//如果需要右旋
        {
            if(x>T->right->data)
            {
                T=rrRotation(T);//RR旋转
            }
            else
            {
                T=rlRotation(T);//RL旋转
            }
        }
    }
    T->height=max(getHeight(T->right),getHeight(T->right))+1;//更新树高
    return T;
}

思路:

建立AVL树,返回该树根结点的值,具体实现细节看代码。如何建立AVL树是这题的重点,关于平衡二叉树的原理和平衡二叉树调整的实例可以看这位博主写的博客

参考资料:

[1]中国大学MOOC.数据结构(浙江大学).平衡二叉树课件
[2]月雲之霄: https://blog.csdn.net/isunbin/article/details/81707606

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
据引用\[1\]和引用\[3\]的内容,构建一个平衡二叉树的过程包括以下几个步骤:输入结点、寻找结点入位置、入结点、判断树是否平衡、调整树的平衡。 首先,通过输入结点的值,从结点开始逐一比较,如果大于结点的值,则继续在结点的右子树中递归寻找入位置;如果小于结点的值,则在结点的左子树中递归寻找入位置。当找到入位置时,创建一个新的结点并将其入。 接下来,利用递归的栈特点,从距离新入结点最近的结点开始,从下往上进行平衡的检测。如果发现树的某个结点不平衡,即左右子树的高度差超过1,就进行旋转操作来调整树的平衡。 据引用\[2\]的内容,旋转操作时需要重新申请一个类型为AVLTree的结点B,并将旋转结果复制到B中。这是为了避免在原有平衡树上进行修改,从而导致错误和重复的部。 因此,练习4.2平衡二叉树可以通过入函数Insert来实现,具体代码可以参考引用\[3\]中的实现思路。在入过程中,每次新申请的结点都需要入,否则将不会有任何改变。 #### 引用[.reference_title] - *1* *2* *3* [PTA练习4.2 平衡二叉树 (25 )](https://blog.csdn.net/Mai___/article/details/119139360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅帅的阿豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值