解题报告-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;
}
本文介绍了一种平衡二叉搜索树——AVL树的构造方法,并通过具体代码实现了解决给定序列构造AVL树并输出根节点值的问题。详细讲解了四种不同情况下的旋转操作,包括LL、RR、LR及RL。
4139

被折叠的 条评论
为什么被折叠?



