题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805404939173888
题意:
给定一个序列,将该序列构建成一颗平衡二叉树,然后输出根节点地元素值。
解题思路:
此题考查数据结构中的平衡二叉树地定义,对于树相关地题,如果能够解决子树问题,那么通过递归地方式可以使得整颗树都达到目标结果。
因此我们根据平衡二叉树的定义,对于任何一颗已经平衡的子树,添加一个节点以后导致不平衡,有四种情况:
1、右孩子节点右子树中添加节点导致失衡 RR旋转。
2、左节点左子树添加节点导致失衡 LL旋转。
3、右孩子左子树中添加节点导致失衡 RL旋转,先RR再LL。
4、左孩子右子树中添加节点导致失衡 LR旋转,先LL再RR。
我们只要考虑到对于节点 n 失衡的原因,然后根据以上原因执行相关操作即可使得树平衡。
解题代码:
#include <bits/stdc++.h>
using namespace std;
struct Node{
Node * r;
Node * l;
int e;//元素
};
Node *avl =NULL;
//获取该节点的最大高度
int getH(Node *n){
if(n==NULL) return 0;
else return 1+max(getH(n->l),getH(n->r));
}
//左左旋转,返回调整以后的根节点,右子树右边添加导致失去平衡
Node *LL(Node *n){
Node *temp;
temp = n->r;
temp ->l = n;
n->r = NULL;
n = temp;
return n;
}
//右右旋转,左子树左添加失去平衡
Node *RR(Node *n){
Node *temp;
temp = n->l;
temp->r = n;
n->l = NULL;
n = temp;
return n;
}
//右左旋转,右孩子的左子树添加失去平衡,先右旋转,再左旋转
Node *RL(Node *n){
n->r = RR(n->r);//右旋转
n = LL(n);//左旋转
return n;
}
//左右旋转,左孩子的右子树添加失去平衡
Node *LR(Node *n){
n->l = LL(n->l);
n = RR(n);
return n;
}
//二叉树添加节点,节点添加
Node *insertTree(Node *n,int e){
if(n==NULL){
n = new Node();
n->l = NULL;
n->r = NULL;
n->e = e;
return n;
}else{
if(n->e>e){//左子树添加
n->l = insertTree(n->l,e);
int hl = getH(n->l);
int hr = getH(n->r);
if(abs(hl-hr)>=2){//失去平衡了
if(e<n->l->e){
n = RR(n);
}else{
n = LR(n);
}
}
}else{
n->r = insertTree(n->r,e);
int hl = getH(n->l);
int hr = getH(n->r);
if(abs(hl-hr)>=2){
if(n->r->e <e){
n = LL(n);
}else{
n = RL(n);
}
}
}
}
return n;
}
void init(){
int num;
cin>>num;
for(int i = 0 ; i <num;i++){
int e;
cin>>e;
avl = insertTree(avl,e);
}
cout<<avl->e;
}
int main()
{
init();
return 0;
}