Skip to content

11211: 【原1211】isCBT

题目

题目描述

author: DS TA 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1211

Description

给出一棵二叉树的结构,判断这棵二叉树是不是完全二叉树。必须使用二叉树类实现。

Input Format

输入文件一共包含N+1行。

第一行含有一个正整数N,代表树中结点总数。

第二行到第N+1行,每行包含二个整数。其中第i行的二个整数Pi,Qi,代表结点i的左孩子为Pi,右孩子为Qi。若Pi=0,则表明结点i没有左孩子。同样的,若Qi=0,则表明结点i没有右孩子。(第i行指的是这N行中的第i行)

Output Format

如果给出的树是完全二叉树,则输出'Y',否则输出'N'。(均不包含引号)

Sample Input1

4
0 0
0 0
1 0
3 2

Sample Output1

Y

Sample Input2

4
0 0
0 0
0 1
3 2

Sample Output2

N

Limit

对于所有的数据,均满足1<=N<=100000

对于所有的数据,均满足0<=Pi,Qi<=N

对于所有的数据,均保证给出的是一棵二叉树

BugenZhao's solution

//
// Created by BugenZhao on 2019/3/31.
//

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

template<typename Item>
class Queue {
    class Node {
    public:
        Item item;
        Node *next = nullptr;
    };

    int N;
    Node *first;
    Node *last;

public:
    Queue() {
        N = 0;
        first = last = nullptr;
    }

    bool isEmpty() {
        return N == 0;
    }

    int size() {
        return N;
    }

    void enqueue(Item item) {
        if (N == 0) {
            first = new Node{item};
            last = first;
        } else {
            Node *tmp = last;
            last = new Node{item};
            tmp->next = last;
        }
        ++N;
    }

    Item dequeue() {
        Item item = first->item;
        Node *tmp = first;
        first = first->next;
        if (N == 1) last = nullptr;
        delete tmp;
        --N;
        return item;
    }

    Item getFirst() {
        return first->item;
    }

    Item getLast() {
        return last->item;
    }

    virtual ~Queue() {
        Node *tmp;
        while (first != nullptr) {
            tmp = first;
            first = first->next;
            delete tmp;
        }
    }
};


// template<typename Item>
class BinaryTree {

    class Node {
    public:
        Node *left = nullptr, *right = nullptr;
        Node *father = nullptr;
        // Item val;
    };

    int size;
    int maxSize;
    Node *root;
    Node **nodes;

public:
    BinaryTree() {
        BinaryTree(5);
    }

    explicit BinaryTree(int maxSize) {
        root = nullptr;
        this->maxSize = maxSize;
        nodes = new Node *[maxSize + 1]{};
        for (int i = 1; i <= maxSize; ++i) {
            nodes[i] = new Node();
        }
        size = 0;
    }

    void add(int left, int right) {
        if (size == maxSize) resize(maxSize * 2);
        ++size;

        nodes[size]->left = nodes[left];
        nodes[size]->right = nodes[right];
        if (left) nodes[left]->father = nodes[size];
        if (right) nodes[right]->father = nodes[size];
    }

    void resize(int newSize) {
        auto oldNodes = nodes;
        nodes = new Node *[newSize + 1]{};
        for (int i = 1; i <= maxSize; ++i) {
            nodes[i] = oldNodes[i];
        }
        for (int i = maxSize + 1; i <= newSize; ++i) {
            nodes[i] = new Node;
        }
        maxSize = newSize;
    }

    void getRoot() {
        Node *p = nodes[1];
        while (p->father) {
            p = p->father;
        }
        root = p;
    }

    bool isCBT() {
        getRoot();

        Queue<Node *> queue;
        queue.enqueue(root);
        Node *p;

        while (p = queue.dequeue()) {
            queue.enqueue(p->left);
            queue.enqueue(p->right);
        }

        while (!queue.isEmpty()) {
            if (p = queue.dequeue()) {
                return false;
            }
        }
        return true;
    }

    virtual ~BinaryTree() {
        for (int i = 1; i <= maxSize; ++i) {
            delete nodes[i];
        }
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    BinaryTree binaryTree(N);
    int a, b;
    for (int i = 0; i < N; ++i) {
        cin >> a >> b;
        binaryTree.add(a, b);
    }

    cout << (binaryTree.isCBT() ? 'Y' : 'N') << endl;
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
#include "cmath"
#include "cstring"
using namespace std;

template <class T>
class mQueue {
    class node {
    public:
        T data;
        node* next = nullptr;
    };
    node* head = nullptr,
        * rear = nullptr;
    size_t _size = 0;

public:
    //构造函数
    mQueue() {
        head = new node;
        rear = head;
    }
    //判断是否为空
    bool empty() {
        return head->next == nullptr;
    }
    //增加
    void push(const T& val) {
        rear->next = new node;
        rear = rear->next;
        rear->data = val;
        ++_size;
    }
    //删除
    void pop() {
        //安全措施
        if (head->next == nullptr)
            return;
        auto temp = head->next;
        delete head;
        head = temp;
        --_size;
    }
    //大小
    size_t size() {
        return _size;
    }
    //最前
    T& front() {
        //安全措施
        return head->next->data;
    }
    //最后
    T& back() {
        //安全措施
        return rear->data;
    }
};

//二叉树类
template <class T>
class myBinaryTree {
public:
    class node {
    public:
        T data;
        node *lchild = nullptr, *rchild = nullptr,*parent=nullptr;
    };
    node *root = nullptr;
    node **nodeList=nullptr;
    int lengthOfNodeList=0;

    //创建树
    void createTree(int num) {
        nodeList = new node*[num+1] {nullptr};
        lengthOfNodeList = num;
    }

    void creadNode(int nodeNum, int lchild, int rchild) {
        if(nodeList[nodeNum]==nullptr)
            nodeList[nodeNum] = new node;

        if (lchild != 0) {
            if (nodeList[lchild] == nullptr)
                        nodeList[lchild] = new node;
            nodeList[lchild]->parent = nodeList[nodeNum];
            nodeList[nodeNum]->lchild = nodeList[lchild];
        }

        if (rchild != 0) {
            if (nodeList[rchild] == nullptr)
                        nodeList[rchild] = new node;
            nodeList[rchild]->parent = nodeList[nodeNum];
            nodeList[nodeNum]->rchild = nodeList[rchild];
        }
    }

    void checkRoot() {
        for (int i = 1; i <= lengthOfNodeList; i++) {
            if (nodeList[i]->parent == nullptr) {
                root = nodeList[i];
                break;
            }
        }
    }

    //清空
    void clear() {
        clear(root);
    }

    void clear(node *p) {
        if (p == nullptr)
            return;
        clear(p->lchild);
        clear(p->rchild);
        delete p;
        p = nullptr;
    }

    //构造
    myBinaryTree() {}

    //析构
    ~myBinaryTree() {
        clear(root);
    }

    //判断是否非空
    bool empty() {
        return root == nullptr;
    }

    //判断是否为完全二叉树
    bool isCBT() {
        if (empty())
            return false;
        //层次遍历
        mQueue<node*> treeQueue;
        bool flag = false;
        //先入队
        treeQueue.push(root);

        //反复
        while (!treeQueue.empty()) {
            //先出队一个
            node* temp = treeQueue.front();
            treeQueue.pop();

            //右孩子有左孩子没有
            if (temp->lchild == nullptr&&temp->rchild != nullptr)
                return false;

            if (!flag) {
                //左孩子有右孩子没有
                if (temp->lchild != nullptr&&temp->rchild == nullptr) {
                    flag = true;
                    //左孩子入队
                    treeQueue.push(temp->lchild);
                }
                //左右孩子都没有
                else if (temp->lchild == nullptr&&temp->rchild == nullptr) {
                    flag = true;
                }
                //左右都有孩子
                else {
                    treeQueue.push(temp->lchild);
                    treeQueue.push(temp->rchild);
                }
            }
            else {
                //判断是否为叶子
                if (temp->lchild != nullptr || temp->rchild != nullptr)
                    return false;
            }
        }

        return true;
    }
};

int main() {
    myBinaryTree<int> bTree;
    int num;
    cin >> num;
    bTree.createTree(num);

    for (int i = 1; i <= num; i++) {
        int lchild, rchild;
        scanf("%d %d", &lchild, &rchild);
        bTree.creadNode(i, lchild, rchild);
    }
    bTree.checkRoot();
    cout << (bTree.isCBT()?"Y":"N");

    return 0;
}

Neight99's solution

#include <iostream>

using namespace std;

const int maxN = 100000;

#include <iostream>

using namespace std;

template <class elemType>
class queue {
   public:
    virtual bool isEmpty() const = 0;
    virtual void enQueue(const elemType &) = 0;
    virtual elemType deQueue() = 0;
    virtual elemType getHead() const = 0;
    virtual ~queue() {}
};

template <class elemType>
class seqQueue : public queue<elemType> {
   private:
    elemType *data;
    int maxSize;
    int front, rear;
    void doubleSpace();

   public:
    seqQueue(int size = maxN + 100);
    ~seqQueue();
    bool isEmpty() const;
    void enQueue(const elemType &);
    elemType deQueue();
    elemType getHead() const;
    int length() const;
};

template <class elemType>
void seqQueue<elemType>::doubleSpace() {
    elemType *tmp = data;
    data = new elemType[maxSize * 2];

    for (int i = 1; i <= maxSize; i++) {
        data[i] = tmp[(front + i) % maxSize];
    }

    front = 0;
    rear = maxSize;
    maxSize *= 2;
    delete[] tmp;
}

template <class elemType>
seqQueue<elemType>::seqQueue(int size) : maxSize(size), front(0), rear(0) {
    data = new elemType[size];
}

template <class elemType>
seqQueue<elemType>::~seqQueue() {
    delete[] data;
}

template <class elemType>
bool seqQueue<elemType>::isEmpty() const {
    return front == rear;
}

template <class elemType>
void seqQueue<elemType>::enQueue(const elemType &x) {
    if ((rear + 1) % maxSize == front) {
        doubleSpace();
    }
    rear = (rear + 1) % maxSize;
    data[rear] = x;
}

template <class elemType>
elemType seqQueue<elemType>::deQueue() {
    front = (front + 1) % maxSize;
    return data[front];
}

template <class elemType>
elemType seqQueue<elemType>::getHead() const {
    return data[(front + 1) % maxSize];
}

template <class elemType>
int seqQueue<elemType>::length() const {
    return ((rear + maxSize - front) % maxSize);
}

template <class T>
class bTree {
   private:
    struct Node {
        T data;
        Node *left;
        Node *right;
        Node *parent;

        Node(T d = 0, Node *p = 0, Node *l = 0, Node *r = 0)
            : data(d), parent(p), left(l), right(r) {}
    };
    Node *nodes[maxN + 100];
    void clear(Node *);

   public:
    Node *root;
    bTree(int n = 10);
    ~bTree();
    void addNode(int, int, T, bool);
    void findRoot();
    void checkTree(int N, Node *p);
};

template <class T>
bTree<T>::bTree(int n) : root(NULL) {
    for (int i = 0; i <= n; i++) {
        nodes[i] = new Node;
    }
}

template <class T>
bTree<T>::~bTree() {
    clear(root);
}

template <class T>
void bTree<T>::clear(Node *p) {
    if (p == NULL) {
        return;
    }

    clear(p->left);
    clear(p->right);
    delete p;
}

template <class T>
void bTree<T>::addNode(int n, int i, T x, bool isRight) {
    if (i != 0 && !isRight) {
        nodes[i]->parent = nodes[n];
        nodes[n]->left = nodes[i];
    } else if (i != 0 && isRight) {
        nodes[i]->parent = nodes[n];
        nodes[n]->right = nodes[i];
    }
    // nodes[n]->data=x;
}

template <class T>
void bTree<T>::findRoot() {
    root = nodes[1];
    while (root->parent != NULL) {
        root = root->parent;
    }
}

template <class T>
void bTree<T>::checkTree(int N, Node *p) {
    int count = 0;
    bool flag = 0;
    seqQueue<Node *> levelNode;
    levelNode.enQueue(p);

    while (count < N) {
        if (!flag && levelNode.getHead()->left == NULL &&
            levelNode.getHead()->right == NULL) {
            flag = 1;
        }

        if (levelNode.getHead()->parent != NULL ||
            levelNode.getHead() == root) {
            count++;
        }

        if (count == N) {
            break;
        }

        if (flag && count < N && levelNode.getHead()->parent == NULL &&
            levelNode.getHead() != p) {
            cout << "N\n";
            return;
        }

        if (levelNode.getHead()->left == NULL) {
            levelNode.getHead()->left = new Node;
        }

        if (levelNode.getHead()->right == NULL) {
            levelNode.getHead()->right = new Node;
        }

        levelNode.enQueue(levelNode.getHead()->left);
        levelNode.enQueue(levelNode.getHead()->right);
        levelNode.deQueue();
    }
    cout << "Y\n";
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int leftNum[maxN + 100], rightNum[maxN + 100], N;

    cin >> N;
    bTree<int> Tree(N);
    for (int i = 1; i <= N; i++) {
        cin >> leftNum[i] >> rightNum[i];
    }

    for (int i = 1; i <= N; i++) {
        Tree.addNode(i, leftNum[i], 0, 0);
        Tree.addNode(i, rightNum[i], 0, 1);
    }

    Tree.findRoot();

    Tree.checkTree(N, Tree.root);

    return 0;
}

skyzh's solution

#include <iostream>
#include <cstdio>
using namespace std;

template <typename T>
struct Queue {
    T* d;
    int f, r;
    Queue(int cap) : d(new T[cap]), f(0), r(0) {}
    bool empty() { return f == r; }
    void enqueue(const T& x) { d[r++] = x; }
    const T dequeue() { return d[f++]; }
    ~Queue() { delete[] d; }
};

template <typename T>
struct Tree {
    T x;
    Tree *l, *r;
    Tree() : l(NULL), r(NULL) {}
    Tree(const T& x, Tree* l = NULL, Tree* r = NULL) : x(x), l(l), r(r) {}
    int children_count() const { return (l ? 1 : 0) + (r ? 1 : 0); }
};

Tree <int> nodes[100005];
bool is_child[100005] = { 0 };

int main() {
    int N, l, r;
    scanf("%d", &N);
    for (int i = 1; i <= N; i++) {
        scanf("%d%d", &l, &r);
        nodes[i].l = l == 0 ? NULL : &nodes[l];
        nodes[i].r = r == 0 ? NULL : &nodes[r];
        is_child[l] = is_child[r] = true;
    }
    int root = 0;
    for (int i = 1; i <= N; i++) if (!is_child[i]) root = i;
    Queue <Tree <int> *> q(400005);
    q.enqueue(&nodes[root]);
    int min_children = 2;
    bool result = true;
    while (!q.empty()) {
        Tree <int> *node = q.dequeue();
        if (node == NULL) {
            min_children = -1;
            continue;
        }
        if (node->children_count() > min_children) result = false;
        min_children = min(min_children, node->children_count());
        q.enqueue(node->l);
        q.enqueue(node->r);
    }
    if (result) cout << "Y" << endl; else cout << "N" << endl;
    return 0;
}

WashSwang's solution

#include <iostream>
#include <cstdio>
using namespace std;
int ls[200000],rs[200000],t[200000],n,d=-1,root;
bool ans=true,sec=true;
void dfs(int i,int depth)
{
    if (ls[i]) dfs(ls[i],depth+1);
    if ((!ls[i])||(!rs[i])) {
        if (d == -1)
            d = depth;
        else {
            if ((depth == d - 1) && sec) {
                d = depth;
                sec = false;
            }
            if (d != depth) ans = false;
        }
    }
    if (rs[i]) dfs(rs[i],depth+1);

}
int main() {
    scanf("%d",&n);
    for (int i=1;i<=n;++i){
        scanf("%d%d",&ls[i],&rs[i]);
        t[ls[i]]++;
        t[rs[i]]++;
    }
    for (int i=1;i<=n;++i)
        if (!t[i]) {
            root=i;
            break;
        }
    dfs(root,1);
    if (ans) printf("Y");
    else printf("N");
    return 0;
}

yyong119's solution

#include <cstdio>
#include <queue>
using namespace std;

const int MAX_N = 100000;
struct node_data {
    int left_child, right_child, father;
} node[MAX_N + 10];

int main() {

    int n; scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        int tmp_left, tmp_right; scanf("%d%d", &tmp_left, &tmp_right);
        node[i].left_child = tmp_left;
        node[tmp_left].father = i;
        node[i].right_child = tmp_right;
        node[tmp_right].father = i;
    }

    int root = 1;
    while (node[root].father) root = node[root].father;
    queue<int> que; que.push(root);
    int cnt = 1; bool flag = true;

    while (!que.empty()) {
        int tmp = que.front(); que.pop();
        if (node[tmp].left_child) {
            que.push(node[tmp].left_child);
            ++cnt;
        }
        else if(cnt < n) {
            flag = false; break;
        }
        if (node[tmp].right_child) {
            que.push(node[tmp].right_child);
            ++cnt;
        }
        else if (cnt < n) {
            flag = false; break;
        }
    }
    if (flag) printf("%c\n", 'Y'); else printf("%c\n", 'N');

    return 0;
}