11043: 【原1043】完全二叉树
题目
题目描述
author: 田力 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1043
Description
给出一棵二叉树,判断其是否为完全二叉树。
Input Format
第一行,N<1000000,表示二叉树节点数。
默认序号为0的节点为树根。接下来共N-1行,依次表示序号为1,...,N-1的节点的父亲节点序号。
如果一个节点有两个孩子节点,左孩子节点序号总是小于右孩子节点序号。
Output Format
仅一行,如果是完全二叉树,则输出true,否则输出false。
Hint
Sample Input1
6
0
1
1
0
4
Sample Output1
true
Sample Input2
6
0
1
1
0
3
Sample Output2
false
FineArtz's solution
/* 完全二叉树 */
#include <iostream>
#include <queue>
using namespace std;
class Node{
public:
int lchild = -1, rchild = -1;
};
Node a[1000005];
bool check(int root){
queue<int> q;
q.push(root);
int t = q.front();
q.pop();
while (t != -1){
q.push(a[t].lchild);
q.push(a[t].rchild);
t = q.front();
q.pop();
}
while (!q.empty()){
t = q.front();
q.pop();
if (t != -1) return false;
}
return true;
}
int main(){
int n, t;
cin >> n;
for (int i = 1; i < n; ++i){
cin >> t;
if (a[t].lchild == -1) a[t].lchild = i;
else a[t].rchild = i;
}
if (check(0)) cout << "true" << endl;
else cout << "false" << 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 child) {
if (nodeList[nodeNum] == nullptr) {
nodeList[nodeNum] = new node;
nodeList[nodeNum]->data = nodeNum;
}
nodeList[child] = new node;
nodeList[child]->data = child;
if (nodeList[nodeNum]->lchild == nullptr) {
nodeList[nodeNum]->lchild = nodeList[child];
}
else {
if (child > nodeList[nodeNum]->lchild->data)
nodeList[nodeNum]->rchild = nodeList[child];
else {
nodeList[nodeNum]->rchild = nodeList[nodeNum]->lchild;
nodeList[nodeNum]->lchild = nodeList[child];
}
}
}
void checkRoot() {
root = nodeList[0];
}
//清空
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;
if (num == 1) {
cout << "true";
return 0;
}
bTree.createTree(num);
for (int i = 1; i < num; i++) {
int temp;
scanf("%d", &temp);
bTree.creadNode(temp, i);
}
bTree.checkRoot();
cout << (bTree.isCBT()?"true":"false");
return 0;
}
q4x3's solution
/**
* 完全二叉树判断
* 凭直觉写
* 草死了二叉树鲨我
**/
#include <stdio.h>
#include <iostream>
using namespace std;
int N;
struct node{
int self;
int fa;
node *left, *right;
node():fa(-1), left(NULL), right(NULL) {}
};
node no[1000233];
int fa[1000233];
void build() {
for(int i = 0;i <= N;++ i) {
no[i].self = i;
no[i].fa = fa[i];
}
for(int i = 0;i < N;++ i) {
node *fano = &(no[fa[i]]);
node *le = fano->left;
if(le) {
if(le->self > i) {
fano->right = le;
fano->left = &(no[i]);
} else {
fano->right = &(no[i]);
}
} else {
if(i) fano->left = &(no[i]);
}
}
}
bool check(node *rt) {
if(rt == NULL) {
return 0;
}
node* che[1000233];
int head = 0, rear = 0;
che[rear ++] = rt;
while(head != rear) {
node *top = che[head];
if(top->left && top->right) {
++ head;
che[rear ++] = top->left;
che[rear ++] = top->right;
} else
if(top->left == NULL && top->right) {
return 0;
} else
if((top->left && top->right == NULL) ||
(top->left == NULL && top->right == NULL)) {
++ head;
while(head != rear) {
top = che[head];
if(top->left == NULL && top->right == NULL) {
++ head;
} else {
return 0;
}
}
return 1;
}
}
return 1;
}
int main() {
scanf("%d", &N);
for(int i = 1;i < N;++ i) {
scanf("%d", &fa[i]);
}
build();
if(check(&(no[0]))) cout << "true" << endl;
else cout << "false" << endl;
return 0;
}
victrid's solution
#include <cstdio>
#include <iostream>
using namespace std;
struct tree {
tree* left;
tree* right;
bool valid;
enum { none,
one,
both } occupied;
tree(int n) : left(nullptr), right(nullptr), valid(true), occupied(none){};
tree() : left(nullptr), right(nullptr), valid(false), occupied(none){};
};
tree nodes[1000001] = {};
//! queue must be large enough to handle a full tree
tree* queuet[4000003] = {nullptr};
tree** queueex;
tree** queueend;
void clearqueue() {
queueex = queuet;
queueend = queuet + 1;
}
void enqueue(tree* tptr) {
*queueend = tptr;
queueend++;
}
tree* dequeue() {
if (queueex + 1 == queueend)
return nullptr;
else
queueex++;
return *queueex;
}
int main() {
int N;
scanf("%d", &N);
int proc;
nodes[0].valid = true;
for (int i = 1; i < N; i++) {
nodes[i].valid = true;
scanf("%d", &proc);
switch (nodes[proc].occupied) {
case tree::none:
nodes[proc].occupied = tree::one;
nodes[proc].left = nodes + i;
break;
case tree::one:
nodes[proc].occupied = tree::both;
nodes[proc].right = nodes + i;
break;
case tree::both:
cout << "false";
return 0;
break;
}
}
clearqueue();
enqueue(nodes);
tree* proce;
int tcount = 0;
proce = dequeue();
while (proce != nullptr) {
if (!proce->valid)
continue;
tcount++;
proce->valid = false;
enqueue(proce->left);
enqueue(proce->right);
proce = dequeue();
}
if (tcount == N)
cout << "true";
else
cout << "false";
return 0;
}
yyong119's solution
#include <iostream>
#include <queue>
using namespace std;
struct treedata{
int l, r, pre;
} tree[1000001];
int n, i, node, now;
bool flag,complete = true;
queue<int> que;
int main(){
cin>>n;
for (int i = 1; i < n; i++){
cin>>node;
tree[i].pre = node;
if (tree[node].l == 0) tree[node].l = i;
else tree[node].r = i;
}
if (tree[0].l) que.push(tree[0].l);
if (tree[0].r) que.push(tree[0].r);
while (!que.empty()){
now = que.front();
que.pop();
if (!tree[now].l&&!tree[now].r) flag = true;
if (tree[now].l){
que.push(tree[now].l);
if (flag){
complete = false;
break;
}
}
if (tree[now].r) que.push(tree[now].r);
}
if (complete) cout<<"true"; else cout<<"false";
return 0;
}
Zsi-r's solution
#include <iostream>
using namespace std;
struct node
{
int leftchild, rightchild;
node() : leftchild(-1), rightchild(-1){};
bool haveonlyleftchild()
{
return leftchild >= 0 && rightchild == -1;
}
bool haveonlyrightchild()
{
return leftchild == -1 && rightchild >= 0;
}
bool havenochild()
{
return leftchild == -1 && rightchild == -1;
}
bool havebothchild()
{
return leftchild >= 0 && rightchild >= 0;
}
};
class que
{
struct n
{
node data;
n *next;
n(const node &x,n*n = NULL)
{
data = x;
next = n;
}
n():next(NULL){}
~n(){}
};
n *front, *rear;
public:
que() { front = rear = NULL; }
bool isempty()
{
return front == NULL;
}
~que() {
n *temp;
while(front!=NULL)
{
temp = front;
front = front->next;
delete temp;
}
}
void enqueue(const node &x)
{
if (rear==NULL)
front = rear = new n(x);
else
{
rear->next = new n(x);
rear = rear->next;
}
}
node dequeue()
{
n *temp = front;
node value = front->data;
front = front->next;
if (front ==NULL)
rear = NULL;
delete temp;
return value;
}
};
class tree
{
friend istream & operator>>(istream &is,tree &obj)
{
int temp;
for (int i = 1; i < obj.len;i++)
{
cin >> temp;
if (obj.list[temp].havenochild())
obj.list[temp].leftchild = i;
else if (obj.list[temp].haveonlyleftchild())
obj.list[temp].rightchild = i;
}
return is;
}
private:
node *list;
int len;
bool iscbt(int n)
{
que q;
if (list[n].havenochild())
return true;
bool flag = false;
q.enqueue(list[n]);
while(!q.isempty())
{
node temp = q.dequeue();
if (temp.haveonlyrightchild())
return false;
if (!flag){
if (temp.havebothchild())
{
q.enqueue(list[temp.leftchild]);
q.enqueue(list[temp.rightchild]);
continue;
}
else if (temp.haveonlyleftchild())
{
q.enqueue(list[temp.leftchild]);
flag = true;
continue;
}
else if (temp.havenochild())
{
flag = true;
continue;
}
}
else{
if (!temp.havenochild())
return false;
}
}
return true;
}
public:
tree(int n){
list = new node[n];
len = n;
}
bool iscbt()
{
return iscbt(0);
}
};
int main()
{
int n;
cin >> n;
tree t(n);
cin >> t;
bool flag = t.iscbt();
if (flag)
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}