1

1123. Is It a Complete AVL Tree (30)

时间限制: 400 ms
内存限制: 65536 kB
代码长度限制: 16000 B
判题程序:Standard

  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.
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   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   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.
Examples
>| Input| | ------------- | | 5
88 70 61 63 65 | | Output | | 70 63 88 61 65
YES |
>| ------------- | >| Input| | 8
88 70 61 96 120 90 65 68| | Output | | 88 65 96 61 70 90 120 68
NO|   Notes   
作者   CHEN, Yue

  下面程序的AVL树是用平衡因子实现的,平衡处理是独立的,再插入操作完成后进行,这样的写法可能更清晰,易于理解。
  判断树是否为完全二叉树的做法是,用一个存储节点指针的queue对树进行层次遍历,从根节点开始,先将其指针加入queue,不断将queue的队首元素的左右节点指针(空指针也加入)加入queue后将队首元素移出,直到queue空为止。在遍历的过程中,queue队首元素第一次为空指针时,如果已经将所有节点遍历完(计数即可),就说明该树为完全二叉树。
  

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <functional>
#include <string>
#include <cstring>
#include <queue>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <sstream>
#include <iomanip>
using namespace std;
#define IOS ios_base::sync_with_stdio(false)
#define TIE std::cin.tie(0)
#define MIN2(a,b) (a<b?a:b)
#define MIN3(a,b) (a<b?(a<c?a:c):(b<c?b:c))
#define MAX2(a,b) (a>b?a:b)
#define MAX3(a,b,c)  (a>b?(a>c?a:c):(b>c?b:c))
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const double PI = 4.0*atan(1.0);
const double eps = 1e-6;

int n, x;

struct AVLTree{
	struct AVLTreeNode{
		int data;
		int balanceFactor;//平衡因子
		AVLTreeNode * left = NULL;
		AVLTreeNode * right = NULL;
		AVLTreeNode(){}
		AVLTreeNode(int item) :data(item){}
	};
	typedef AVLTreeNode * AVLTreeNodePointer;
	void insert(int item);
	void adj();
	int adjAux(AVLTreeNodePointer & subtreeRoot, int h);
	void leftSingleRotation(AVLTreeNodePointer & subtreeRoot);
	void rightSingleRotation(AVLTreeNodePointer & subtreeRoot);
	void leftDoubleRotation(AVLTreeNodePointer & subtreeRoot);
	void rightDoubleRotation(AVLTreeNodePointer & subtreeRoot);
	void levelorder(AVLTreeNodePointer subtreeRoot) const;
	AVLTreeNodePointer myRoot = NULL;
};

void AVLTree::insert(int item)
{
	AVLTreeNodePointer locptr = myRoot;				 //查找指针
	AVLTreeNodePointer parent = 0;
	bool found = false;						 //表示item是否已存在于树中
	while (!found && locptr != 0)
	{
		parent = locptr;
		if (item < locptr->data)             //下降到左子树
			locptr = locptr->left;
		else if (locptr->data < item)        //下降到右子树
			locptr = locptr->right;
		else
			found = true;                    //item被找到
	}
	if (!found)								 //item未被找到
	{
		//创建包含item的节点
		locptr = new AVLTreeNode(item);
		if (parent == 0)					 //当前树为空
			myRoot = locptr;
		else if (item < parent->data)        //作为父亲节点的左孩子插入
			parent->left = locptr;
		else
			parent->right = locptr;          //作为父亲节点的右孩子插入
	}
	else
		;//item已存在 
}

void AVLTree::adj()
{
	adjAux(myRoot, 1);
}

int AVLTree::adjAux(AVLTreeNodePointer & subtreeRoot, int h)
{
	//参数height为节点的高度,设定根节点的高度为1,自顶向下逐层的高度依次加1
	int leftHeight = 0, rightHeight = 0;
	if (subtreeRoot != NULL)
	{
		h++;                                                 //高度增加1
		leftHeight = adjAux(subtreeRoot->left, h);    //左子树相对根节点的高度
		rightHeight = adjAux(subtreeRoot->right, h);  //右子树相对根节点的高度
		subtreeRoot->balanceFactor = leftHeight - rightHeight;    //计算平衡因子

		if (subtreeRoot->balanceFactor == 2)                      //左子树高
		{
			if (subtreeRoot->left->balanceFactor == 1)            //右单旋
				rightSingleRotation(subtreeRoot);
			else if (subtreeRoot->left->balanceFactor == -1)      //右双旋
				rightDoubleRotation(subtreeRoot);
			return adjAux(subtreeRoot, h - 1);        //旋转调整后重新计算平衡因子
		}
		else if (subtreeRoot->balanceFactor == -2)				  //右子树高
		{
			if (subtreeRoot->right->balanceFactor == -1)          //左单旋
				leftSingleRotation(subtreeRoot);
			else if (subtreeRoot->right->balanceFactor == 1)      //左双旋
				leftDoubleRotation(subtreeRoot);
			return adjAux(subtreeRoot, h - 1);		  //旋转调整后重新计算平衡因子
		}
		else                                                      //不需调整,返回左子树和右子树树高的最大值
		{                                                         //即为父亲节点的高度
			return max(leftHeight, rightHeight);
		}
	}
	else
		return h;                                             //节点为空
}

void AVLTree::leftSingleRotation(AVLTreeNodePointer & subtreeRoot)
{
	AVLTreeNodePointer rightTree = subtreeRoot->right;
	subtreeRoot->right = rightTree->left;
	rightTree->left = subtreeRoot;
	subtreeRoot = rightTree;
}

void AVLTree::rightSingleRotation(AVLTreeNodePointer & subtreeRoot)
{
	AVLTreeNodePointer leftTree = subtreeRoot->left;
	subtreeRoot->left = leftTree->right;
	leftTree->right = subtreeRoot;
	subtreeRoot = leftTree;
}

void AVLTree::leftDoubleRotation(AVLTreeNodePointer & subtreeRoot)
{
	AVLTreeNodePointer rightTree = subtreeRoot->right,
		child = rightTree->left;

	//右旋
	rightTree->left = child->right;
	child->right = rightTree;
	subtreeRoot->right = child;

	//左旋
	subtreeRoot->right = child->left;
	child->left = subtreeRoot;
	subtreeRoot = child;
}

void AVLTree::rightDoubleRotation(AVLTreeNodePointer & subtreeRoot)
{
	AVLTreeNodePointer leftTree = subtreeRoot->left,
		child = leftTree->right;

	//左旋
	leftTree->right = child->left;
	child->left = leftTree;
	subtreeRoot->left = child;

	//右旋
	subtreeRoot->left = child->right;
	child->right = subtreeRoot;
	subtreeRoot = child;
}

void AVLTree::levelorder(AVLTreeNodePointer subtreeRoot) const
{
	queue<AVLTreeNodePointer> que;
	que.push(myRoot);
	bool first = true, nullfir=true;
	bool cmp = false;
	int cnt = 0;
	while (!que.empty()){
		AVLTreeNodePointer ptr = que.front();
		que.pop();
		if (ptr == NULL){
			if (nullfir){
				nullfir = false;
				if (cnt == n)
					cmp = true;
			}
			continue;
		}
		cnt++;
		if(first) first = false;
		else printf(" ");
		printf("%d", ptr->data);
		que.push(ptr->left);
		que.push(ptr->right);
	}
	printf("\n%s\n", cmp ? "YES" : "NO");
}

int main()
{
	AVLTree tree;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &x);
		tree.insert(x);
		tree.adj();
	}
	tree.levelorder(tree.myRoot);
	//system("pause");
}
//system("pause");
posted @ 2017-03-03 11:31  Cumulonimbus  阅读(114)  评论(0编辑  收藏  举报