PAT A1066 Root of AVL Tree
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:
一、模拟AVL树的建立:
- create():将输入序列依次
insert()
到树上 - insert():再BST得基础上,还要保证|平衡因子| < 2,所以我们还需要一个
getBalanceFactor()
,一但插入使某一节点得平衡因子达到2,就需要调整,调整需要:左旋L()
和右旋R()
- getBalanceFactor():每个结点得平衡因子都为其左子树高度 - 右,所有我们需要每次插入时实时更新高度
updateHeight()
- updateHeight():每个结点得高度,就是其左右子树高度最大值+1,所有还需要一个
getHeight()
,以及每个结点中应存有记录高度的变量height
二、调整方式:
如题所示,插入破坏平衡的情况可以分为4种:LL, LR, RR, RL(当前结点root 的左孩子的左子树上插入 / 左孩子的右子树插入 / …)
LL: 对root右旋(往左边偏,向右边掰直; RR: 对root左旋
LR: 先对root-lchild右旋,即可转化为LL; RL: 同理root->rchild左旋->RR
三、左右旋:
L():左旋(一定是向右偏)
按元素从小到大排列为:aL < (a) < bL < b < bR
所以上树,等价于:aL < a < bL < (b) < bR
从上面两图可以看到,bL上插入一个结点,会导致a失衡,而通过一次左旋,恰好将其抵消掉了(且左旋后的树等价于旋转前)
变化有:
bL: (b->rc) --> (a->lc)
b:(root->rc) --> (root)
a:(root) --> (b->lc)
=》设置一个临时指针指向b:
1) root->rc = tmp->lc;
2) tmp->lc = root;
3) tmp = root;
(!!!:别忘了更新变化过的结点(a和b)的高度变化!!!)
- TIPS 1:
1) L/R 、2) insert都需要加&,需要改变root的原值
- code 1:
#include <iostream>
using namespace std;
const int maxn = 110;
int n, input[maxn];
struct node{
int data, height;
node *lc, *rc;
};
node* newNode(int x){
node* n = new node;
n->data = x;
n->height = 1;
n->lc = n->rc = NULL;
return n;
}
int getHeight(node* root){
if(root == NULL) return 0;
return root->height;
}
int updateHeight(node* root){
root->height = max(getHeight(root->lc), getHeight(root->rc)) + 1;
}
int getBalanceFactor(node* root){
return getHeight(root->lc) - getHeight(root->rc);
}
void L(node* &root){
node * tmp = root->rc;
root->rc = tmp->lc;
tmp->lc = root;
updateHeight(root);
updateHeight(tmp);
root = tmp;
}
void R(node* &root){
node * tmp = root->lc;
root->lc = tmp->rc;
tmp->rc = root;
updateHeight(root);
updateHeight(tmp);
root = tmp;
}
void insert(node* &root, int x){
if(root == NULL){
root = newNode(x);
return;
}
if(x < root->data){
insert(root->lc, x);
updateHeight(root);
if(getBalanceFactor(root) == 2){ //L型
if(getBalanceFactor(root->lc) == 1){ //LL型
R(root);
}else if(getBalanceFactor(root->lc) == -1){ //LR型
L(root->lc);
R(root);
}
}
}else{
insert(root->rc, x);
updateHeight(root);
if(getBalanceFactor(root) == -2){ //R型
if(getBalanceFactor(root->rc) == -1){ //RR型
L(root);
}else if(getBalanceFactor(root->rc) == 1){ //RL型
R(root->rc);
L(root);
}
}
}
}
node* create(){
node* root = NULL;
for(int i = 0; i < n; ++i){
insert(root, input[i]);
}
return root;
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d", &input[i]);
node* r = create();
printf("%d", r->data);
return 0;
}
- 思路 2:静态树实现版
- code 2:
#include <iostream>
using namespace std;
const int maxn = 110;
int n, input[maxn], idex = 0;
struct Node{
int data, height, lc, rc;
}node[maxn];
int newNode(int x){
idex++;
node[idex].data = x;
node[idex].lc = node[idex].rc = -1;
node[idex].height = 1;
return idex;
}
int getHeight(int root){
if(root == -1) return 0;
return node[root].height;
}
void updateHeight(int root){
node[root].height = max(node[node[root].lc].height, node[node[root].rc].height) + 1;
}
int getBalanceFactor(int root){
//return node[node[root].lc].h - node[node[root].rc].h; //Wrong 1:
return getHeight(node[root].lc) - getHeight(node[root].rc);
}
void L(int &root){
int tmp = node[root].rc;
///node[root].rc = tmp; //Wrong 2:
node[root].rc = node[tmp].lc;
node[tmp].lc = root;
updateHeight(root);
updateHeight(tmp);
root = tmp;
}
void R(int &root){
int tmp = node[root].lc;
node[root].lc = node[tmp].rc;
node[tmp].rc = root;
updateHeight(root);
updateHeight(tmp);
root = tmp;
}
void insert(int &root, int x){
if(root == -1){
root = newNode(x);
return;
}
if(x < node[root].data){
insert(node[root].lc, x);
updateHeight(root);
if(getBalanceFactor(root) == 2){
if(getBalanceFactor(node[root].lc) == 1){ //LL
R(root);
}else if(getBalanceFactor(node[root].lc) == -1){ //LR
L(node[root].lc);
R(root);
}
}
}else{
insert(node[root].rc, x);
updateHeight(root);
if(getBalanceFactor(root) == -2){
if(getBalanceFactor(node[root].rc) == -1){ //RR
L(root);
}else if(getBalanceFactor(node[root].rc) == 1){ //RL
R(node[root].rc);
L(root);
}
}
}
}
int create(){
int root = -1;
for(int i = 0; i < n; ++i) insert(root, input[i]);
return root;
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d", &input[i]);
int r = create();
printf("%d", node[r].data);
return 0;
}