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
分析:判断是否是完全二叉树。先求根节点,可以设置一个数组child,如果输入过程中如果该结点被当做孩子节点那它一定不是根节点,输入完毕后从头开始遍历child数组,第一个是false的child[i]跳出,i就是根节点。
那么如何判断是完全二叉树呢?
这里提供两种方法。
1、层序遍历,每次把空节点也Push进队列中,完全二叉树层序遍历过程中,如果遇到空节点了,说明一定已经遍历完非空节点;而对非完全二叉树,如果遇到空节点了,后面还必定有非空节点。于是遍历过程中用一个变量统计已入队过的节点数量。
2、递归求最大下标值,完全二叉树中,最大下标值=最大结点数(起始为1); 而非完全二叉树中,最大下标值>最大结点数
代码分别如下:
1 /**
2 * Copyright(c)
3 * All rights reserved.
4 * Author : Mered1th
5 * Date : 2019-02-26-21.04.42
6 * Description : A1110
7 */
8 #include<cstdio>
9 #include<cstring>
10 #include<iostream>
11 #include<cmath>
12 #include<algorithm>
13 #include<string>
14 #include<unordered_set>
15 #include<map>
16 #include<vector>
17 #include<set>
18 #include<queue>
19 using namespace std;
20 struct Node{
21 int l,r;
22 }node[30];
23 bool child[30]={false};
24 int maxd=-1,n;
25 bool isCBT(int root){
26 int cnt=0;
27 queue<int>q;
28 q.push(root);
29 while(!q.empty()){
30 int top=q.front();
31 q.pop();
32 if(top!=-1){
33 maxd=top;
34 cnt++;
35 q.push(node[top].l);
36 q.push(node[top].r);
37 }
38 else{
39 if(cnt==n) return true;
40 else return false;
41 }
42 }
43 }
44
45 int main(){
46 #ifdef ONLINE_JUDGE
47 #else
48 freopen("1.txt", "r", stdin);
49 #endif
50 cin>>n;
51 string a,b;
52 for(int i=0;i<n;i++){
53 cin>>a>>b;
54 if(a[0]=='-'){
55 node[i].l=-1;
56 }
57 else{
58 node[i].l=stoi(a);
59 child[stoi(a)]=true;
60 }
61 if(b[0]=='-'){
62 node[i].r=-1;
63 }
64 else{
65 node[i].r=stoi(b);
66 child[stoi(b)]=true;
67 }
68 }
69 int root;
70 for(int i=0;i<n;i++){
71 if(child[i]==false){
72 root=i;
73 break;
74 }
75 }
76 if(isCBT(root)) printf("YES %d",maxd);
77 else printf("NO %d",root);
78 return 0;
79 }
这里利用了二叉树静态存储的性质,即父节点和叶子节点之间的关系。
1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<cmath>
5 #include<algorithm>
6 #include<queue>
7 using namespace std;
8 struct node{
9 int data;
10 int l,r;
11 }Node[100];
12 int cnt=1,n;
13 bool hashtable[100]={false};
14 /*void LayerOrder(int root){
15 queue<int> Q;
16 Q.push(root);
17 while(!Q.empty()){
18 int now=Q.front();
19 Q.pop();
20 if(Node[now].l!=-1){
21 if(Node[now].r!=-1){
22 cnt++;
23 Q.push(Node[now].l);
24 }
25 else{
26 cnt++;
27 }
28 }
29 if(Node[now].r!=-1){
30 if(Node[now].l!=-1){
31 cnt++;
32 Q.push(Node[now].r);
33 }
34 else{
35 cnt++;
36 }
37 }
38 }
39 }
40 */
41 int maxn=-1,ans;
42 void dfs(int root,int index){
43 //求出最大下标值,如果下标值等于最大节点数-1则说明是完全二叉树,若大于最大结点数-1则非完全二叉树
44 if(index>maxn){
45 maxn=index;
46 ans=root;
47 }
48 if(Node[root].l!=-1) dfs(Node[root].l,index*2);
49 if(Node[root].r!=-1) dfs(Node[root].r,index*2+1);
50 }
51 int main(){
52 #ifdef ONLINE_JUDGE
53 #else
54 freopen("1.txt", "r", stdin);
55 #endif
56 cin>>n;
57 string t1,t2;
58 for(int i=0;i<n;i++){
59 cin>>t1>>t2;
60 Node[i].data=i;
61 if(t1=="-"){
62 Node[i].l=-1;
63 }
64 else{
65 Node[i].l=stoi(t1);
66 hashtable[stoi(t1)]=true;
67 }
68 if(t2=="-"){
69 Node[i].r=-1;
70 }
71 else{
72 Node[i].r=stoi(t2);
73 hashtable[stoi(t2)]=true;
74 }
75 }
76 int i;
77 for(i=0;i<n;i++){
78 if(hashtable[i]==false) break;
79 }
80 dfs(i,1);
81 if(maxn==n){
82 cout<<"YES "<<ans;
83 }
84 else{
85 cout<<"NO "<<i;
86 }
87 return 0;
88 }