解題報告-PAT - Root of AVL Tree
原題鏈接:https://pta.patest.cn/pta/test/1342/exam/4/question/20492
ZOJ:1066題
題意:給定一個輸入序列,構造平衡二叉樹,每個案例輸出根節點的值。
關於平衡二叉樹定義等等,可參考有關資料或者課本,這裏只就旋轉操作,做簡要說明。
根據嚴蔚敏的教材,我們把在構造平衡二叉樹中的旋轉操作分爲:
LL(左子樹的左子樹插入):右單旋
RR(右子樹的右子樹插入):左單旋
LR(左子樹的右子樹插入):左旋旋小部分,右旋旋大部分
RL(右子樹的左子樹插入):右旋旋小部分,左旋旋大部分
這四個插入均是相對於失衡結點來說的。
源碼:
# include <stdio.h>
# include <stdlib.h>
typedef struct Node *AvlTree;
typedef struct Node *Position;
struct Node{
int data;
struct Node *l;
struct Node *r;
int height;
};
/*
AVL樹的旋轉
*/
AvlTree Insert(int x,AvlTree T);//insert into the tree and if need, we will rotate the tree
Position SingleRotateWithLeft(Position a); //左單旋 RR插入
Position SingleRotateWithRight(Position a); //右單旋 LL插入
Position DoubleRotateWithLR(Position a); //左右旋 LR插入
Position DoubleRotateWithRL(Position a); //右左旋 RL插入
int Max(int x1,int x2); //求最大值函數
int Height(Position p); //返回一個結點的高度
/*
插入方式 旋轉方式
LL 右單旋
RR 左單旋
LR 左旋小部分,右旋大部分
RL 右旋小部分,左旋大部分
*/
int main(){
int n,x;
AvlTree T = NULL;
scanf("%d",&n);
for(int i=0; i<n; i++){
scanf("%d",&x);
T = Insert(x,T);
}
printf("%d\n",T->data);
return 0;
}
//結點插入
AvlTree Insert(int x, AvlTree T){
if(T == NULL){
T=(AvlTree)malloc(sizeof(struct Node));
T->data=x;
T->l = T->r = NULL;
T->height = 0;
}else if(x < T->data){//向左子樹插入
T->l = Insert(x,T->l);
if(Height(T->l) - Height(T->r) == 2){
if(x < T->l->data) //LL插入
T = SingleRotateWithRight(T);
else //LR插入
T = DoubleRotateWithLR(T);
}
}else if(x > T->data){//向右子樹插入
T->r = Insert(x,T->r);
if(Height(T->r) - Height(T->l) == 2){
if(x > T->r->data) //RR插入
T = SingleRotateWithLeft(T);
else //LR插入
T = DoubleRotateWithRL(T);
}
}
/*更新節點高度*/
T->height = Max(Height(T->l), Height(T->r)) + 1;
return T;
}
Position SingleRotateWithRight(Position a){//右單旋 LL插入
Position b = a->l;
a->l = b->r;
b->r = a;
//更新a, b節點高度
a->height = Max(Height(a->l), Height(a->r)) + 1;
b->height = Max(Height(b->l), Height(b->r)) + 1;
return b; /*新的根節點*/
}
Position SingleRotateWithLeft(Position a){ //左單旋 RR插入
Position b = a->r;
a->r = b->l;
b->l = a;
//更新a,b節點高度
b->height = Max(Height(b->l), Height(b->r)) + 1;
a->height = Max(Height(a->l), Height(a->r)) + 1;
return b; /*新的根節點*/
}
Position DoubleRotateWithLR(Position a){ //左右旋 LR插入
a->l = SingleRotateWithLeft(a->l);
return SingleRotateWithRight(a);
}
Position DoubleRotateWithRL(Position a){ //右左旋 RL插入
a->r = SingleRotateWithRight(a->r);
return SingleRotateWithLeft(a);
}
int Max(int x1,int x2){ //求最大值函數
return (x1 > x2) ? x1:x2;
}
int Height(Position p){ //返回一個結點的高度
if(p==NULL)
return -1;
return p->height;
}