解题报告-PAT - Root of AVL Tree

解题报告-PAT - Root of AVL Tree

原题链接:https://pta.patest.cn/pta/test/1342/exam/4/question/20492

ZOJ:1066题

题意:给定一个输入序列,构造平衡二叉树,每个案例输出根节点的值。

关于平衡二叉树定义等等,可参考有关资料或者课本,这里只就旋转操作,做简要说明。

根据严蔚敏的教材,我们把在构造平衡二叉树中的旋转操作分为:

 LL(左子树的左子树插入):右单旋

RR(右子树的右子树插入):左单旋

LR(左子树的右子树插入):左旋旋小部分,右旋旋大部分

RL(右子树的左子树插入):右旋旋小部分,左旋旋大部分

这四个插入均是相对于失衡结点来说的。

解题报告-PAT - Root of AVL Tree_第1张图片

解题报告-PAT - Root of AVL Tree_第2张图片

解题报告-PAT - Root of AVL Tree_第3张图片

解题报告-PAT - Root of AVL Tree_第4张图片


源码:

# include 
# include 
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; idata);	
	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;
} 







你可能感兴趣的:(ACMer养成)