[分析】
这题就是完全考完全二叉树定义和性质的一道题。主要还是定义:对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
所以判断二叉树是否为完全二叉树,就要获取其对应满二叉树的顶点编号的信息。
容易想到用层序遍历二叉树就能给顶点编号,开始时,我采用在顶点出队的时候给顶点依次递增编号,后来发现这样其实是不对的,因为只有存在的结点会入队,那些对应满二叉树缺失的结点无法体现。所以应该在判断子结点是否入队的时候也对入队的结点计数,碰到子节点为空,就直接break。再判断总计数是否与结点数相等即可。另外,还要注意题目是否会有不合法的样例,造成层序遍历循环入队之类的问题。
还有一个巨坑的点!!!:
//注意下标可能是两位数,不能只用一个字符储存!!!!
【代码】
这是开始时自己写的代码,出队时计数,答案不对。
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct Node
{
int lchild, rchild;
int num, addr;
}nodes[25];
bool hashT[25] = {false};
int LayerOrder(int root, int &tail) {
queue<Node*> q;
int num = 0;
bool inq[25] = {false};
q.push(&nodes[root]);
inq[root] = true;
while(!q.empty()) {
Node* top = q.front();
tail = top->addr;
top->num = num;
q.pop();
if(top->lchild != -1 && inq[top->lchild] == false) {
inq[top->lchild] = true;
q.push(&nodes[top->lchild]);
}
if(top->rchild != -1 && inq[top->rchild] == false) {
inq[top->rchild] = true;
q.push(&nodes[top->rchild]);
}
}
return num;
}
bool cmp(Node &a, Node &b) {
return a.num < b.num;
}
int main() {
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
nodes[i].addr = i;
}
char a, b;
for(int i = 0; i < n; i++) {;
getchar();
scanf("\n%c%*c%c", &a, &b);
if(a == '-') {
nodes[i].lchild = -1;
}
else {
nodes[i].lchild = a - '0';
hashT[a-'0'] = true;
}
if(b == '-') {
nodes[i].rchild = -1;
}
else {
nodes[i].rchild = b - '0';
hashT[b-'0'] = true;
}
}
// find the root
int root;
for(int i = 0; i < n; i++) {
if(hashT[i] == false) {
root = i;
break;
}
}
int tail;
int num = LayerOrder(root, tail);
if(num != n) {
printf("NO %d\n", root);
}
else {
printf("Yes %d\n", tail);
}
return 0;
}
正确代码
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct Node
{
int lchild, rchild;
int num, addr;
Node():lchild(-1), rchild(-1){};
}nodes[25];
bool hashT[25] = {false};
int LayerOrder(int root, int &tail) {
queue<Node*> q;
int num = 1;
q.push(&nodes[root]);
while(!q.empty()) {
Node* top = q.front();
q.pop();
if(top->lchild != -1) {
q.push(&nodes[top->lchild]);
tail = top->lchild;
num++;
}
else {
break;
}
if(top->rchild != -1 ) {
q.push(&nodes[top->rchild]);
tail = top->rchild;
num++;
}
else {
break;
}
}
return num;
}
int main() {
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
nodes[i].addr = i;
}
//注意下标可能是两位数,不能只用一个字符储存!!!!
// char a, b;
char a[3], b[3];
for(int i = 0; i < n; i++) {;
getchar();
scanf("\n%s %s", a, b);
if(a[0] == '-') {
nodes[i].lchild = -1;
}
else {
nodes[i].lchild = atoi(a);
hashT[atoi(a)] = true;
}
if(b[0] == '-') {
nodes[i].rchild = -1;
}
else {
nodes[i].rchild = atoi(b);
hashT[atoi(b)] = true;
}
}
// find the root
int root;
for(int i = 0; i < n; i++) {
if(hashT[i] == false) {
root = i;
break;
}
}
int tail = root;
int num = LayerOrder(root, tail);
if(num != n) {
printf("NO %d\n", root);
}
else {
printf("YES %d\n", tail);
}
return 0;
}