[分析】
這題就是完全考完全二叉樹定義和性質的一道題。主要還是定義:對於深度爲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;
}