mooc作业题:Root of AVL Tree

Root of AVL Tree

题目描述

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print the root of the resulting AVL tree in one line.

Sample Input 1:
5
88 70 61 96 120

Sample Output 1:
70

Sample Input 2:
7
88 70 61 96 120 90 65

Sample Output 2:
88

思路:
本题主要是学会平衡二叉树的几种旋转方法以及何时进行旋转。旋转过程的描述一定要画图,根据图来写代码,这样会简单很多。其次本题用到很多递归的思想,这是树结构中常用的算法,要深刻体会。

#include<cstdlib>
#include<stdio.h>

typedef struct Treenode* Tree;
Tree maketree(int n); //建树
Tree newnode(int data); //创建新节点
Tree Insert(Tree T, int data); //插入节点
int height(Tree T); //计算树的高度
Tree LLrotation(Tree T);
Tree LRrotation(Tree T);
Tree RRrotation(Tree T);
Tree RLrotation(Tree T);

//定义
struct Treenode{
    int data;
    Tree left;
    Tree right;
};

//主程序
int main()
{
    int n;
    scanf("%d\n", &n);
    Tree T = maketree(n); //是程序的主要部分,返回最后的根节点
    printf("%d", T->data);
    return 0;
}

Tree maketree(int n)
{
    int v;
    scanf("%d", &v);
    Tree T = newnode(v); //根节点单独写出

    for(int i = 1; i < n; i++)
    {
        scanf("%d", &v);
        T = Insert(T, v);
    }
    return T;
}

Tree newnode(int data)
{
    Tree T = (Tree)malloc(sizeof(struct Treenode));
    T->data = data;
    T->left = 0;
    T->right = 0;
    return T;
}

Tree Insert(Tree T, int data)
{
    if(!T) {T = newnode(data);} //递归终止条件
    else {
        if(data < T->data){
            T->left = Insert(T->left, data); 
            if(height(T->left) - height(T->right) == 2)
                if(data < T->left->data) //新节点在左子树的左边
                    T = LLrotation(T);
                else T = LRrotation(T); //新节点在左子树的右边
        }
        else{
            T->right = Insert(T->right, data);
            if(height(T->right) - height(T->left) == 2)
                if(data > T->right->data) //新节点在右子树的右边
                    T = RRrotation(T);
                else T = RLrotation(T); //新节点在右子树的左边
        }
    }
    return T;
}

//求树的最大深度,其实一行代码可以解决
int height(Tree T)
{
    int max, hl, hr;
    if(T)
    {
        hl = height(T->left);
        hr = height(T->right);
        max = hl>hr?hl:hr;
        return max + 1;
    }
    else return 1;
    
    //一行代码版
    //return T?1:(max(height(T->left), height(T->right))+1);
}

//下面开始写旋转的函数,最好是将图形画出来,很快就能写完
Tree LLrotation(Tree T)
{
    Tree a = T, b = T->left; //交换的节点
    Tree ar = a->right, bl = b->left, br = b->right; //附属节点
    b->right = a;
    b->left = bl;
    a->left = br;
    a->right = ar;
    return b;
}

Tree LRrotation(Tree T)
{
    Tree a = T, b = T->left, c = b->right;
    Tree ar = a->right, bl = b->left, cl = c->left, cr = c->right;
    c->left = b; c->right = a;
    b->left = bl; b->right = cl;
    a->left = cr; a->right = ar;
    return c;
}

Tree RRrotation(Tree T)
{
    Tree a = T, b = T->right;
    Tree al = a->left, bl = b->left, br = b->right;
    b->left = a; b->right = br;
    a->left = al; a->right = bl;
    return b;
}

Tree RLrotation(Tree T)
{
    Tree a = T, b = T->right, c = b->left;
    Tree al = a->left, br = b->right, cl = c->left, cr = c->right;
    c->left = a; c->right = b;
    a->left = al; a->right = cl;
    b->left = cr; b->right = br;
    return c;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值