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

1人阅读 评论(0) 收藏 举报
分类:

题目来源:中国大学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;
}

查看评论

Python 数据挖掘与机器学习进阶实训-5

-
  • 1970年01月01日 08:00

04-树5 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 sub...
  • qq_24942951
  • qq_24942951
  • 2017-04-10 22:58:47
  • 160

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

04-树5 Root of AVL Tree   (25分) An AVL tree is a self-balancing binary search tree. In an AVL ...
  • sysusyf
  • sysusyf
  • 2016-03-28 18:41:31
  • 281

PAT 数据结构 04-树4. 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 sub...
  • tuzigg123
  • tuzigg123
  • 2015-07-12 18:25:51
  • 508

04-树5 Root of AVL Tree

/*===================================================================================== # COPY...
  • The__Apollo
  • The__Apollo
  • 2016-12-03 14:21:31
  • 327

04-树3. Root of AVL Tree.zip

  • 2015年06月03日 10:29
  • 471KB
  • 下载

【PAT】1066. Root of AVL Tree (25)

题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1066 题目描述: An AVL tree is a self-balancing ...
  • realxuejin
  • realxuejin
  • 2013-10-19 16:16:52
  • 2032

PAT (Advanced Level) 1066. Root of AVL Tree (25) AVL树的插入建树

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub...
  • tuzigg123
  • tuzigg123
  • 2015-07-28 15:32:31
  • 439

PAT A 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 chil...
  • xyzchenzd
  • xyzchenzd
  • 2014-05-24 12:53:16
  • 563

04-树6 Complete Binary Search Tree 完全二叉搜索树

这道题大意是这样,输入N个不同的非负整数,需要将其按照二叉搜索树的规则,排成一个完全二叉树。二叉搜索树是指每个每个节点的所有左元素都比它小,右边都比它大;完全二叉树指的是,除了最后一层,其余每一层都满...
  • Roland_WuZF
  • Roland_WuZF
  • 2015-10-24 23:02:19
  • 2226
    个人资料
    持之以恒
    等级:
    访问量: 637
    积分: 290
    排名: 27万+
    文章存档