04-树5 Root of AVL Tree(25 分)

题目来源:中国大学MOOC-陈越、何钦铭-数据结构-2018春
作者: DS课程组
单位: 浙江大学

问题描述:
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

解答:
AVL树首先是一棵搜索树,所以根的左边都会比根小,根的右边都会比根大,尝试了下投机取巧排序输出中位数,这题能拿17分(逃

#include <algorithm>
using namespace std;
const int maxn=20;
int input[maxn];
int main()
{
  int N;
  cin>>N;
  for(int i=0;i<N;i++)
  {
    cin>>input[i];
  }
  sort(input,input+N);
  if(N%2!=0)
    cout<<input[(N-1)/2];
  else
    cout<<input[N/2];
  return 0;
}

正经来说,需要建一棵AVL树,即在建立二叉搜索树的过程中,当插入一个节点递归调用返回上一层后,需要对当前根节点的左右子树高度进行判断,是否需要旋转。
当需要旋转时,判断是进行左旋左右旋还是右旋右左旋,即把哪个子节点提到根节点,并做相应变化:
可以设发现不平衡的节点称为节点A,新插入引起不平衡的节点称为节点B
A发现不平衡的情况有四种:

  • B插入到A的左子树的左子树
  • B插入到A的左子树的右子树
  • B插入到A的右子树的左子树
  • B插入到A的右子树的右子树

相对应的,第一种情况只需要左单旋(LL旋)即往右旋转,第四种情况只需要右单旋(RR旋)即往左旋转,比较难理解的是第二种和第四种情况。插入到A的左子树的右子树我们可以对A的左子树先右单旋一次,调整为需要左单旋的状态(LL状态),再整体对A左单旋一次,整体往右旋转调整;同理,插入到A的右子树的左子树,我们需要对A的右子树的左子树做一次向右旋转,调整为需要右单旋的状态(RR状态),右单旋即可。

旋转后要更新左右子树的高度值
head->height=maxHeight(getHeight(head->rightChild),getHeight(head->leftChild))+1;
当最后返回根节点时,一颗AVL树已经构造完毕。

#include <iostream>

using namespace std;

struct node
{
    int value;
    node* rightChild;
    node* leftChild;
    int height;
};
int maxHeight(int temp1,int temp2)
{
    return temp1>temp2?temp1:temp2;
}
int getHeight(node* root)
{
    if(root==NULL)
        return 0;
    else
        return root->height;
}
node* RR(node* root)
{
    node* temp=root;
    root=root->rightChild;
    temp->rightChild=root->leftChild;
    root->leftChild=temp;
    temp->height=maxHeight(getHeight(temp->rightChild),getHeight(temp->leftChild))+1;
    root->height=maxHeight(getHeight(root->rightChild),getHeight(root->leftChild))+1;
    return root;
}
node* LL(node* root)
{
    node* temp=root;
    root=root->leftChild;
    temp->leftChild=root->rightChild;
    root->rightChild=temp;
    temp->height=maxHeight(getHeight(temp->rightChild),getHeight(temp->leftChild))+1;
    root->height=maxHeight(getHeight(root->rightChild),getHeight(root->leftChild))+1;
    return root;
}
node* RL(node* root)
{
    root->rightChild=LL(root->rightChild);
    return RR(root);
}
node* LR(node* root)
{
    root->leftChild=RR(root->leftChild);
    return LL(root);
}
node* buildTree(int value,node* head)
{
    if(head==NULL)
    {
        node* temp=new node();
        temp->value=value;
        temp->height=1;
        return temp;
    }
    if(value>head->value)
    {
        head->rightChild=buildTree(value,head->rightChild);
        if(getHeight(head->rightChild)-getHeight(head->leftChild)==2)
        {
            if(value>head->rightChild->value)
            {
                head=RR(head);
            }
            else
            {
                head=RL(head);
            }
        }
    }
    else
    {
        head->leftChild=buildTree(value,head->leftChild);
        if(getHeight(head->leftChild)-getHeight(head->rightChild)==2)
        {
            if(value<head->leftChild->value)
            {
                head=LL(head);
            }
            else
            {
                head=LR(head);
            }
        }
    }
    head->height=maxHeight(getHeight(head->rightChild),getHeight(head->leftChild))+1;
    return head;
}
int main()
{
    int N;
    cin>>N;
    node* tree=NULL;
    for(int i=1;i<=N;i++)
    {
        int value;
        cin>>value;
        tree=buildTree(value,tree);
    }
    cout<<tree->value;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值