PAT甲级A1123 Is It a Complete AVL Tree (30 分)

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

F1.jpg F2.jpg
F3.jpg F4.jpg

Now given a sequence of insertions, you are supposed to output the level-order traversal sequence of the resulting AVL tree, and to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤ 20). Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, insert the keys one by one into an initially empty AVL tree. Then first print in a line the level-order traversal sequence of the resulting AVL tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line. Then in the next line, print YES if the tree is complete, or NO if not.

Sample Input 1:

5
88 70 61 63 65

Sample Output 1:

70 63 88 61 65
YES

Sample Input 2:

8
88 70 61 96 120 90 65 68

Sample Output 2:

88 65 96 61 70 90 120 68
NO

题意:给出n个数,让你建立一棵avl树,并输出其层序序列,如果这是一棵完全二叉树在输出yes,否则输出no。

思路:首先使用模板建立一棵AVL树,树结点结构如下 

struct node{
	int v,height;    //分别表示权值和高度
	node* lchild;
	node* rchild;
	node(int d,int h_):v(d),height(h_),lchild(NULL),rchild(NULL){}
};

设结点平衡因子为当前结点左孩子高度-右孩子结点高度。根据当前结点root的平衡因子和root的左右孩子平衡因子情况分四种情况。 

平衡因子值  
root=2,root->lchild=1 右旋(root)
root=2,  root->lchild=-1 左旋(root->lchild),右旋(root)
root=-2, root->rchild=-1 左旋(root)
root=-2, root->rchild=1 右旋(root->rchild),左旋(root)

AVL建立完毕后,使用层序遍历这棵树,只要当前结点不空就把结点的左右孩子入队(孩子是空结点也入队),当队列中出现空结点,如果此时后面还有非空结点,则表明这不是一棵完全二叉树。

参考代码: 

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
	int v,height;	//结点权值,高度
	node* lchild;
	node* rchild;
	node(int d,int h_):v(d),height(h_),lchild(NULL),rchild(NULL){}
};
int n,t;
int getHeight(node* root){
	if(root==NULL) return 0;
	else return root->height;
}
void updateHeight(node*& root){		//更新节点高度
	root->height=max(getHeight(root->lchild),getHeight(root->rchild))+1;
}
int getBalanceFactor(node* root){		//获取平衡因子
	return getHeight(root->lchild)-getHeight(root->rchild);
}
void L(node*& root){		//左旋+更新节点高度
	node* temp=root->rchild;
	root->rchild=temp->lchild;
	temp->lchild=root;
	updateHeight(root);
	updateHeight(temp);
	root=temp;
}
void R(node*& root){		//右旋+更新节点高度
	node* temp=root->lchild;
	root->lchild=temp->rchild;
	temp->rchild=root;
	updateHeight(root);
	updateHeight(temp);
	root=temp;
}
void insert(node*& root,int x){		//建树
	if(root==NULL){
		root=new node(x,1);
		return;
	}else if(x<root->v){
		insert(root->lchild,x);
		updateHeight(root);
		if(getBalanceFactor(root)==2){
			if(getBalanceFactor(root->lchild)==1)
				R(root);
			else if(getBalanceFactor(root->lchild)==-1){
				L(root->lchild);
				R(root);
			}
		}
	}else{
		insert(root->rchild,x);
		updateHeight(root);
		if(getBalanceFactor(root)==-2){
			if(getBalanceFactor(root->rchild)==-1){
				L(root);
			}else if(getBalanceFactor(root->rchild)==1){
				R(root->rchild);
				L(root);
			}
		}
	}
}
bool BFS(node* root){		//层序输出结果
	if(root==NULL) return true;
	queue<node*> q;
	q.push(root);
	bool flag1=true,flag2=true;		//flag1标记是否是完全二叉树,flag2标记队列中是否已经出现过空结点
	while(!q.empty()){
		node* p=q.front();
		q.pop();
		if(p!=NULL){
			if(p==root) printf("%d",p->v);
			else printf(" %d",p->v);
			if(!flag2) flag1=false;
			q.push(p->lchild);
			q.push(p->rchild);
		}else 
			flag2=false;		//队列中有空结点,flag2=false
	}
	return flag1;
}
int main()
{
	scanf("%d",&n);
	node* root=NULL;
	for(int i=0;i<n;i++){
		scanf("%d",&t);
		insert(root,t);
	}
	if(BFS(root)) printf("\nYES\n");
	else printf("\nNO\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/vir_lee/article/details/88352404