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