【PAT-A1110】complete binary tree

[分析】

这题就是完全考完全二叉树定义和性质的一道题。主要还是定义:对于深度为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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值