solution Of 1066. Root of AVL Tree (25)

48 篇文章 0 订阅

1066. Root of AVL Tree (25)

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 ythe 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


结题思路 :
题意要求我们输出平衡二叉树的根节点的值。
要求1:每棵子树的左右子树高度差不得超过1;
要求2:每次进行插值以后需要对表现高度差超过阈值的节点的子树进行高度调整;
要求3:在节点A的左子树的左子树进行插入引起的A的高度变化超过阈值,需要进行一次leftSingleRotation;
要求4:在节点A的右子树的右子树进行插入引起的A的高度变化超过阈值,需要进行一次rightSingleRotation;
要求5:在节点A的左子树的右子树进行插入引起的A的高度变化超过阈值,需要进行一次rightSingleRotation和leftSingleRotation;
要求6:在节点A的右子树的左子树进行插入引起的A的高度变化超过阈值,需要进行一次leftSingleRotation和rightSingleRotation;
这里写图片描述
图片转自:http://www.linuxidc.com/Linux/2014-12/110490.htm
程序步骤:
第一步、将每个读入的数据插入到平衡二叉树中; (此处未完成节点的删除)
第二步、输出平衡二叉树的根节点即可。

具体程序(AC)如下:

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct avlNode{
    int value;
    avlNode* left;
    avlNode* right;
    int height;
    avlNode(int value,avlNode* l,avlNode* r,int height):value(value),left(l),right(r),height(height){}
};
int max(int a,int b)
{
    return a>b?a:b;
}
int height(avlNode* root)
{
    return (root==NULL)?-1:root->height;
}
void leftSingleRotation(avlNode* &root)//仅进行指针的移动↑
{
    avlNode* resultRoot=root->left;
    root->left=resultRoot->right;
    resultRoot->right=root;
    root->height=max(height(root->left),height(root->right))+1;
    resultRoot->height=max(height(resultRoot->left),height(resultRoot->right))+1;
    root=resultRoot;
}
void rightSingleRotation(avlNode* &root)//仅进行指针的移动↑
{
    avlNode* resultRoot=root->right;
    root->right=resultRoot->left;
    resultRoot->left=root;
    root->height=max(height(root->left),height(root->right))+1;
    resultRoot->height=max(height(resultRoot->left),height(resultRoot->right))+1;
    root=resultRoot;
}
void leftDoubleRotation(avlNode* &root)
{
    rightSingleRotation(root->left);
    leftSingleRotation(root);
}
void rightDoubleRotation(avlNode* &root)
{
    leftSingleRotation(root->right);
    rightSingleRotation(root);
}
void insert(int value,avlNode * &t)
{
    if(!t)
        t=new avlNode(value,NULL,NULL,0);
    else if(value<t->value)
    {
        insert(value,t->left);
        if(height(t->left)-height(t->right)==2)//在左子树插入结点后,不可能右子树比左子树高2
            if(value<t->left->value)
                leftSingleRotation(t);//左单旋转
            else
                leftDoubleRotation(t);//左双旋转
        else//只需要重新计算其高度
            t->height=max(height(t->left),height(t->right))+1;
    }
    else if(value>t->value)
    {
        insert(value,t->right);
        if(height(t->right)-height(t->left)==2)
            if(value>t->right->value)
                rightSingleRotation(t);//右单旋转
            else
                rightDoubleRotation(t);//右双旋转
        else//只需要重新计算其高度
            t->height=max(height(t->left),height(t->right))+1;
    }
 }
avlNode *root=NULL;
int main()
{
    int N,value;
    cin>>N;
    for(int i=0;i<N;++i)
    {
        cin>>value;
        insert(value,root);
    }
    cout<<root->value<<endl;
    return 0;
}

加个尾巴(AVL Tree的删除部分)

void remove(int value,avlNode* &root)
{//默认avl树中不存在相同的树
    if(!root)return;//树为空,不做处理
    if(value<root->value)
    {
        remove(value,root->left);
        if(height(root->right)-height(root->left)==2)//删除节点以后对高度的重新调整
        {
            //右子树比左子树高2,那么在删除操作之前右子树比左子树高1,即右子树必不为空
            avlNode *s=root->right;
            if(height(s->left)>height(s->right))
                rightDoubleRotation(root);//右双旋转
            else
                rightSingleRotation(root);//右单旋转
        }
        else
            root->height=max(height(root->left),height(root->right))+1;
    }
    else if(value>root->value)
    {
        remove(value,root->right);
        if(height(root->left)-height(root->right)==2)
        {
            avlNode *s=root->left;
            if(height(s->right)>height(s->left))
                leftDoubleRotation(root);//左双旋转
            else
                leftSingleRotation(root);//左单旋转
        }
        else
            root->height=max(height(root->left),height(root->right))+1;
    }
    else
    {
        if(root->left&&root->right)//在这个节点中填充子树中这个节点值的前序(A)或后继(B),然后在对应子树中删除A/B
        {
            if(height(root->left)>height(root->right))
            {
                //左子树中的最大值的索引
                root->value=maxNode(root->left)->value;
                remove(root->value,root->left);
            }
            else
            {
                //右子树中的最小值的索引
                root->value=minNode(root->right)->value;
                remove(root->value,root->right);
            }
        }
        else
        {
            avlNode *s=root;
            root=root->left?root->left:root->right;
            delete s;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值