PAT甲级——1110 Complete Binary Tree (完全二叉树)

时间:2023-03-09 13:31:09
PAT甲级——1110 Complete Binary Tree (完全二叉树)
1110 Complete Binary Tree (25 分)

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 (≤) 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进行标记,每一行代表了一个节点的左孩子和右孩子的信息,若没有孩子,以'-'代替。要求判断它是否为完全二叉树,若是完全二叉树则输出"YES"以及最后一个节点的值,反之输出“NO”和根节点的值。

思路:建立二叉树 —> 寻找根节点 —> 判断是否为完全二叉树。二叉树用数组储存,将'-'转换成-1来标明左孩子或者右孩子为空;用bool数组isRoot来给孩子节点进行标记,然后遍历isRoot寻找根节点;最后进行完全二叉树的判断,判断的依据是:层序遍历该二叉树,1、若当前节点的左孩子为空,右孩子不为空,则非完全二叉树;2、若发现某个节点没有右孩子则进行标记,在这之后入队的节点如果不是叶子节点那么就不是完全二叉树。

 #include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
struct node {
int key, left, right;
};
int getNum(string &s);
bool isComplete(vector <node> &tree, int root, int &lastNode);
int main()
{
int N, root, lastNode;
scanf("%d", &N);
vector <node> tree(N);
vector <bool> isRoot(N, true);
for (int i = ; i < N; i++) {
string s1,s2;
cin >> s1 >> s2;
tree[i].key = i;
tree[i].left = getNum(s1);
tree[i].right = getNum(s2);
if (tree[i].left != -)
isRoot[tree[i].left] = false;
if (tree[i].right != -)
isRoot[tree[i].right] = false;
}
for (int i = ; i < N; i++)
if (isRoot[i]) {
root = i;
break;
}
bool flag = isComplete(tree, root, lastNode);
if (flag)
printf("YES %d\n", lastNode);
else
printf("NO %d\n", root);
return ;
}
bool isComplete(vector <node> &tree, int root, int &lastNode) {
bool flag = false;
queue <int> Q;
Q.push(root);
int t;
while (!Q.empty()) {
t = Q.front();
Q.pop();
if (tree[t].left == - && tree[t].right != -)
return false;
if (flag) {//在标记之后再次发现非叶子节点,不是完全二叉树
if (!(tree[t].left == - && tree[t].right == -)) {
return false;
}
}
if (tree[t].right == -)//如果发现某个节点没有右孩子,就标记下,在这之后进入队列的节点要都是叶子节点才能满足完全二叉树的性质
flag = true;
if (tree[t].left != -)
Q.push(tree[t].left);
if (tree[t].right != -)
Q.push(tree[t].right);
if (Q.empty())
lastNode = tree[t].key;
}
return true;
}
int getNum(string &s) {
if (s[] == '-')
return -;
int n = ;
for (int i = ; i<s.length(); i++)
n = n * + s[i] - '';
return n;
}