1110 Complete Binary Tree (25 point(s))
Given a tree, you are supposed to tell if it is a complete binary tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤20) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a -
will be put at the position. Any pair of children are separated by a space.
Output Specification:
For each case, print in one line YES
and the index of the last node if the tree is a complete binary tree, or NO
and the index of the root if not. There must be exactly one space separating the word and the number.
Sample Input 1:
9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -
Sample Output 1:
YES 8
Sample Input 2:
8
- -
4 5
0 6
- -
2 3
- 7
- -
- -
Sample Output 2:
NO 1
题意:
给出N个结点,标记为0~N-1,对于接下来的N行,每一行给出其左右孩子。判断这棵树是否是完全二叉树,如果是输出它最后一个结点,否则输出这棵树的根。
知识点:
1. 完全二叉树的定义、层次遍历的特点;
2. BFS。
思路:
1. 在输入的过程中,标记儿子结点。输入结束后仍然没有被标记的结点是树的根节点;
2. 想象树的层次遍历,如果补全成一颗完全二叉树(-1),对于本身就是一棵完全二叉树,那么这个序列就会是N的元素加上一连串的-1。因此从1中得到的根节点开始层次遍历,如果没有遇到-1,计数加1,且这是当前的最后一个结点;如果遇到了-1说明这是这棵树的子图(到这个结点为止的满足定义的完全二叉树)的结点数,如果等于N则说明是完全二叉树,否则不是。
3. 根据2的情况,输出结果。
注意点:
1. 根节点寻找的方法。如在长度是n的数组中寻找3:find(a,a+n,3)-a
2. 完全二叉树的层次遍历特点
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
struct Node{
int left,right;
};
int toIndex(string s){
if(s=="-") return -1;
int ans = 0;
for(int i=0;i<s.length();i++){
ans = ans*10+s[i]-'0';
}
return ans;
}
int N;Node node[27];
bool visit[27]={false};
bool levelOrder(int root,int& last){
queue<int> q;
q.push(root);
int cnt = 0;
while(!q.empty()){
int top = q.front();
q.pop();
if(top!=-1){
cnt++;
last = top;
}
else{
return cnt==N;
}
q.push(node[top].left);
q.push(node[top].right);
}
}
int main(void){
string l,r;cin>>N;
for(int i=0;i<N;i++){
cin>>l>>r;
if(l!="-"){
node[i].left = toIndex(l);
visit[toIndex(l)]=true;
}
else node[i].left=-1;
if(r!="-"){
node[i].right = toIndex(r);
visit[toIndex(r)]=true;
}
else node[i].right=-1;
}
int root = find(visit,visit+N,false)-visit;//寻找root
int last = -1;
bool flag = levelOrder(root,last);
if(flag) cout<<"YES "<<last<<endl;
else cout<<"NO "<<root<<endl;
return 0;
}