Problem Description
给定一棵二叉树,判断其是否是AVL树(平衡二叉树),如果不是AVL树的话,输出”NOT AVL TREE!!!”以及不平衡的结点个数;否则判断其是否是一棵完全二叉树,如果不是完全二叉树的话,输出”NOT COMPLETE TREE!!!” 以及结点个数饱和的最后一层层号(假设根结点层号为1,且第i层的结点个数饱和是指该层的结点个数等于2^(i-1));否则将这棵完全二叉树经过若干次向下调整变成大顶堆,输出”OHHHHH HEAP!!!”以及此过程中将父结点与子结点交换的总次数(每次父结点与子结点交换都算一次,即同一轮向下调整的过程中可能有多次交换)。
Input
每个输入文件中一组数据。
第一行一个正整数N(N<=20),代表二叉树的结点个数(结点编号为1到N)。
第二行按结点编号从小到大的顺序给出N个结点的权值(各结点的权值均小于20且各不相同)。
接下来按结点编号从小到大的顺序给出N行,每行为两个编号,分别代表该结点的左孩子编号和右孩子编号,如果不存在左(右)孩子,那么就用字符’-‘代替。数据保证编号在1到N之间。
Output
分两行按题目描述中的字符串和相应统计结果。
Sample Input
5
1 2 3 4 5
2 3
4 5
- -
- -
- -
Sample Output
OHHHHH HEAP!!!
3
Author
Shoutmon
Source
17浙大考研机试模拟赛
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> nodeval;
int rts[32],n;
bool isAVL=true;
int ubcounts=0;
bool isCBT=true;
int levcnt[32];
int exchange=0;
int A[32];
struct TreeNode
{
int val;
int left,right;
TreeNode(int v=0,int l=0,int r=0):val(v),left(l),right(r){}
}T[32];
int toindex(string str)
{
if(str[0]=='-') return -1;
return stoi(str);
}
int solve(int r,int i,int depth)
{
if(r==-1) return 0;
int lh=solve(T[r].left,2*i,depth+1);
int rh=solve(T[r].right,2*i+1,depth+1);
if(i>n) isCBT=false;
levcnt[depth]++;
if(i<=n) A[i]=nodeval[r];
if(abs(lh-rh)>=2) isAVL=false,ubcounts++;
return max(lh,rh)+1;
}
void Adjust(int s,int e)
{
int temp=A[s];
int parent=s,child;
while(2*parent<=e)
{
child=2*parent;
if(child<e&&A[child]<A[child+1]) ++child;
if(temp>A[child]) break;
A[parent]=A[child];
parent=child;
++exchange;
}
A[parent]=temp;
}
int main()
{
cin>>n;
nodeval.resize(n+1);
for(int i=1;i<=n;++i)
cin>>nodeval[i];
for(int i=1;i<=n;++i)
{
string L,R;
cin>>L>>R;
int left=toindex(L),right=toindex(R);
T[i].left=left;
T[i].right=right;
if(left!=-1)rts[left]=1;
if(right!=-1)rts[right]=1;
}
int root=1;
while(rts[root]==1) ++root;
solve(root,1,1);
if(!isAVL)
{
cout<<"NOT AVL TREE!!!\n"<<ubcounts<<endl;
return 0;
}
if(!isCBT)
{
cout<<"NOT COMPLETE TREE!!!\n";
int lv=1,nodes=1;
while(levcnt[lv]==nodes)
{
nodes*=2;
++lv;
}
cout<<lv-1<<endl;
return 0;
}
cout<<"OHHHHH HEAP!!!\n";
for(int i=n/2;i>=1;--i)
Adjust(i,n);
cout<<exchange<<endl;
return 0;
}