PAT甲级 1066 Root of AVL Tree(25) (平衡二叉树)

这篇博客介绍了PAT甲级考试中的一道关于AVL树的问题,涉及如何构建和保持平衡二叉搜索树。通过示例输入和输出,解释了插入序列后AVL树的根节点确定,并探讨了四种平衡调整情况。代码实现是解决该问题的关键部分。

题目

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.

输入

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.

输出

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

样例输入 

样例输入1:

5
88 70 61 96 120
样例输入2:

7
88 70 61 96 120 90 65

样例输出 

样例输出1:

70
样例输入2:

88

题意理解

题意很好理解 就是给你一个序列 构建一颗二叉平衡树

最后让你输出根结点的值

那么其中的难点就是平衡二叉树的构建

我们将平衡二叉树不平衡的情况分为以下四种情况 将对四种情况分别讨论如何继续保持平衡

1:在根节点的左孩子的左子树中插入一个新结点

 2:在根节点的右孩子的右子树中插入一个新结点

 3:在根节点的左孩子的右子树中插入一个新结点

  4:在根节点的右孩子的左子树中插入一个新结点

以上就是如何保持平衡的

注意平衡树是一种特殊的二叉排序树

就是先保持二叉排序树 然后再维持树的平衡

那么剩下具体的看代码就可以 

代码 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef struct Node{
    int data;
    Node *l,*r;
}Node;
Node *Left(Node *root){
    Node *p=root->r;
    root->r=p->l;
    p->l=root;
    return p;
}
Node *Right(Node *root){
    Node *p=root->l;
    root->l=p->r;
    p->r=root;
    return p;
}
Node *LeftRight(Node *root){
    root->l=Left(root->l);
    return Right(root);
}
Node *RightLeft(Node *root){
    root->r=Right(root->r);
    return Left(root);
}
int get_height(Node *root){
    if(root==NULL)return 0;
    return max(get_height(root->l),get_height(root->r))+1; 
}
Node* insert(Node *root,int x){
      if(root==NULL){
          root=new Node;
          root->data=x;
          root->l=root->r=NULL;
          return root;
      }
      else if(x<root->data){
          root->l=insert(root->l,x);
          if(get_height(root->l)-get_height(root->r)==2){
              if(x<root->l->data){
                  root=Right(root);
              }
              else{
                  root=LeftRight(root);
              }
          }
      }
    else {
          root->r=insert(root->r,x);
          if(get_height(root->l)-get_height(root->r)==-2){
              if(x>root->r->data){
                  root=Left(root);
              }
              else{
                  root=RightLeft(root);
              }
          }
    }
    return root;
}
int main(){
    int n;
    cin>>n;
    Node *root=NULL;
    for(int i=0,x;i<n;i++){
        scanf("%d",&x);
        root=insert(root,x);
    }
    printf("%d\n",root->data);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值