解題報告-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(右子樹的左子樹插入):右旋旋小部分,左旋旋大部分

這四個插入均是相對於失衡結點來說的。






源碼:

# 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;
} 







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章