PAT甲级1123 Is It a Complete AVL Tree//建平衡二叉树//判断是否为完全二叉树

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 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

题目大意

给出一串数字用来建立平衡二叉树,最后水平遍历这个平衡二叉树,同时还有说出这个树是否为完全二叉树

思路

这个题目考察的东西很多,也可以作为一个比较综合的例题用来学习。首先是建立平衡二叉树的几个关键函数

int get_height(node* root)
{
	if (!root)
		return 0;
	return root->height;
}
int get_balance_factor(node* root)
{
	return get_height(root->left) - get_height(root->right);
}
void update_height(node* root)
{
	root->height = max(get_height(root->left), get_height(root->right)) + 1;
}
void L(node* &root) //左旋
{
	node* temp = root->right;
	root->right = temp->left;
	temp->left = root;
	update_height(root);
	update_height(temp);
	root = temp;
}
void R(node* &root) //右旋
{
	node* temp = root->left;
	root->left = temp->right;
	temp->right = root;
	update_height(root);
	update_height(temp);
	root = temp;
}

其次是如何通过水平遍历判断是否为完全二叉树

void levelOrder(node* root)
{
	bool flag = false;
	queue<node*> Q;
	Q.push(root);
	while (!Q.empty())
	{
		node* front = Q.front();
		if (front != NULL)
		{
			if (flag) //flag为true的情况下还有结点说明肯定不是完全二叉树
				isComplete = false;
			Q.push(front->left);
			Q.push(front->right);
		}
		else
			flag = true; //如果为空表示之后不再会有结点
		if (front != NULL)
			ans.push_back(front->val);
		Q.pop();
	}
}

完整代码:

#include <iostream>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct node
{
	int val;
	int height;
	node* left;
	node* right;
	node(int v) : val(v), height(1), left(NULL), right(NULL) {}
};
bool isComplete = true;
vector<int> ans;
int get_height(node* root);
int get_balance_factor(node* root);
void update_height(node* root);
void L(node* &root);
void R(node* &root);
void insert(node* &root, int v);
void levelOrder(node* root);
int main()
{
	int N;
	cin >> N;
	node* root = NULL;
	for (int i = 0; i < N; i++)
	{
		int val;
		cin >> val;
		insert(root, val); //建树
	}
	levelOrder(root); //水平遍历
	for (int i = 0; i < ans.size(); i++)
	{
		if (i != 0)
			cout << " ";
		cout << ans[i];
	}
	cout << endl;
	if (isComplete)
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
	system("pause");
	return 0;
}
int get_height(node* root)
{
	if (!root)
		return 0;
	return root->height;
}
int get_balance_factor(node* root)
{
	return get_height(root->left) - get_height(root->right);
}
void update_height(node* root)
{
	root->height = max(get_height(root->left), get_height(root->right)) + 1;
}
void L(node* &root)
{
	node* temp = root->right;
	root->right = temp->left;
	temp->left = root;
	update_height(root);
	update_height(temp);
	root = temp;
}
void R(node* &root)
{
	node* temp = root->left;
	root->left = temp->right;
	temp->right = root;
	update_height(root);
	update_height(temp);
	root = temp;
}
void insert(node* &root, int v)
{
	if (!root)
	{
		root = new node(v);
		return;
	}
	if (v < root->val)
	{
		insert(root->left, v);
		update_height(root);
		if (get_balance_factor(root) == 2) //LL or LR
		{
			if (get_balance_factor(root->left) == 1) //LL
				R(root);
			else if (get_balance_factor(root->left) == -1)//LR
			{
				L(root->left);
				R(root);
			}
		}
	}
	else
	{
		insert(root->right, v);
		update_height(root);
		if (get_balance_factor(root) == -2) //RL or RR
		{
			if (get_balance_factor(root->right) == 1) //RL
			{
				R(root->right);
				L(root);
			}
			else if (get_balance_factor(root->right) == -1)//RR
				L(root);
		}
	}
}
void levelOrder(node* root)
{
	bool flag = false;
	queue<node*> Q;
	Q.push(root);
	while (!Q.empty())
	{
		node* front = Q.front();
		if (front != NULL)
		{
			if (flag)
				isComplete = false;
			Q.push(front->left);
			Q.push(front->right);
		}
		else
			flag = true;
		if (front != NULL)
			ans.push_back(front->val);
		Q.pop();
	}
}

第二种判断是否为平衡二叉树的方法

联系堆的结构,我们很容易想到,对于完全二叉树,其层序遍历结果可以用一个数组来表示,这里我们的根节点数组下标为0。那么对于数组下标为x的节点,其左孩子节点的数组下标必然是2 * x + 1,其右孩子节点的数组下标必然是2 * x + 2。
我们只需将层序遍历的结果保存进一个数组中,对该数组进行中序遍历即可。如果中序遍历的结果是非降序排列,则说明这是一棵完全二叉树;否则,不是一棵完全二叉树。

/*
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
struct node
{
	int val;
	int height;
	node* left;
	node* right;
	node(int v) : val(v), height(1), left(NULL), right(NULL) {}
};
vector<int> level, in;
void inOrder(int);
int get_height(node* root);
int get_balance_factor(node* root);
void update_height(node* root);
void L(node* &root);
void R(node* &root);
void insert(node* &root, int v);
void levelOrder(node* root);
int main()
{
	int N;
	cin >> N;
	node* root = NULL;
	for (int i = 0; i < N; i++)
	{
		int val;
		cin >> val;
		insert(root, val);
	}
	levelOrder(root);
	for (int i = 0; i < level.size(); i++)
	{
		if (i != 0)
			cout << " ";
		cout << level[i];
	}
	*/
	inOrder(0); //对数组进行遍历
	cout << endl;
	for (int i = 1; i < in.size(); i++)
	{
		if (in[i] < in[i - 1])
		{
			cout << "NO" << endl;
			system("pause");
			return 0;
		}
	}
	cout << "YES" << endl;
	system("pause");
	return 0;
}
/*int get_height(node* root)
{
	if (!root)
		return 0;
	return root->height;
}
int get_balance_factor(node* root)
{
	return get_height(root->left) - get_height(root->right);
}
void update_height(node* root)
{
	root->height = max(get_height(root->left), get_height(root->right)) + 1;
}
void L(node* &root)
{
	node* temp = root->right;
	root->right = temp->left;
	temp->left = root;
	update_height(root);
	update_height(temp);
	root = temp;
}
void R(node* &root)
{
	node* temp = root->left;
	root->left = temp->right;
	temp->right = root;
	update_height(root);
	update_height(temp);
	root = temp;
}
void insert(node* &root, int v)
{
	if (!root)
	{
		root = new node(v);
		return;
	}
	if (v < root->val)
	{
		insert(root->left, v);
		update_height(root);
		if (get_balance_factor(root) == 2) //LL or LR
		{
			if (get_balance_factor(root->left) == 1) //LL
				R(root);
			else if (get_balance_factor(root->left) == -1)//LR
			{
				L(root->left);
				R(root);
			}
		}
	}
	else
	{
		insert(root->right, v);
		update_height(root);
		if (get_balance_factor(root) == -2) //RL or RR
		{
			if (get_balance_factor(root->right) == 1) //RL
			{
				R(root->right);
				L(root);
			}
			else if (get_balance_factor(root->right) == -1)//RR
				L(root);
		}
	}
}
*/
void levelOrder(node* root)
{
	bool flag = false;
	queue<node*> Q;
	Q.push(root);
	//这里改为正常水平遍历
	while (!Q.empty())
	{
		node* front = Q.front();
		if (front->left != NULL)
			Q.push(front->left);
		if (front->right != NULL)
			Q.push(front->right);
		level.push_back(front->val);
		Q.pop();
	}
}
//将水平遍历后的数组level进行中序遍历
void inOrder(int root)
{
	if (root >= level.size())
		return;
	inOrder(root * 2 + 1);
	in.push_back(level[root]);
	inOrder(root * 2 + 2);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值