PAT 1110 Complete Binary Tree C++ 版
1.题意
给出一棵树的层次遍历+左右子节点,判断其是否是一棵完全二叉树(complete binary tree
,后文简称CBT
)。
2.分析
判断一棵完全二叉树可以借用层次遍历即可。判断是否为完全二叉树的理论如下:
- case1:如果节点有右节点但是没有左节点,则肯定不是
CBT
- case2:如果当前节点是最后一个有子树的节点(有左子树或者左右子树都有,但是按照层次遍历的顺序时,其后面的节点却有左子树或者右子树)那么就不是一棵CBT。
3.代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define maxn 100
using namespace std;
int N;
int fa[maxn];//每个节点的父节点 [根节点的父节点为0]
queue<int> que;
int ele;//队中元素
struct Node{
int left,right;//左右两个节点
int data;//当前节点值
};
Node node[maxn];
//寻找根节点
int findRoot(int sour){
while(fa[sour]!=sour){
sour = fa[sour];
}
return sour;
}
//层次遍历 && 是否是一棵Complete Binary Tree
bool isCBT(int root){
bool first = false;
bool flag = true;//是否是一棵CBT
que.push(root);//入队列
while(!que.empty()){//队列非空
ele = que.front();
que.pop();//出队
if(node[ele].left!=-1) que.push(node[ele].left);
if(node[ele].right!=-1) que.push(node[ele].right);
//case 1:左子树不存在,右子树存在的
if(node[ele].left==-1 && node[ele].right!=-1){
flag = false;
}
//case 2:
if(first && (node[ele].left != -1 || node[ele].right!=-1) ){//违反了CBT的规则
flag = false;
}
if( node[ele].right == -1 && !first ){//如果右子树为null,且尚未置
first = true;
}
}
return flag;
}
int main(){
cin >> N;
int i,j;
string left,right;//表示左右两个子树
for(i= 0;i< N;i++){
fa[i] = i;
}
for(i = 0;i< N;i++){
cin >> left >> right;
if(left.compare("-") == 0){
node[i].left = -1;//左子树为-1
}
else {
node[i].left = stoi(left);
fa[stoi(left)] = i;
}
if(right.compare("-") == 0){
node[i].right = -1;//左子树为-1
}
else{
node[i].right = stoi(right);
fa[stoi(right)] = i;
}
node[i].data = i;
}
int root = findRoot(0);
if(isCBT(root)) {
cout << "YES "<<ele<<"\n" ;
}
else cout <<"NO "<<root<<"\n";
}
4.测试用例
9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -
8
- -
4 5
0 6
- -
2 3
- 7
- -
- -
//测只有左子树,没有右子树
8
- -
4 5
0 -
- -
2 3
6 7
- -
- -
Yes 0
8
- -
4 5
0 7
- -
2 3
6 -
- -
- -
5.执行结果
一次AC啦,啦啦啦啦