1110 Complete Binary Tree (25 point(s))

1110 Complete Binary Tree (25 point(s))

Given a tree, you are supposed to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤20) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a - will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each case, print in one line YES and the index of the last node if the tree is a complete binary tree, or NO and the index of the root if not. There must be exactly one space separating the word and the number.

Sample Input 1:

9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -

Sample Output 1:

YES 8

Sample Input 2:

8
- -
4 5
0 6
- -
2 3
- 7
- -
- -

Sample Output 2:

NO 1

题意:

给出N个结点,标记为0~N-1,对于接下来的N行,每一行给出其左右孩子。判断这棵树是否是完全二叉树,如果是输出它最后一个结点,否则输出这棵树的根。

知识点:

1. 完全二叉树的定义、层次遍历的特点;

2. BFS。

思路:

1. 在输入的过程中,标记儿子结点。输入结束后仍然没有被标记的结点是树的根节点;

2. 想象树的层次遍历,如果补全成一颗完全二叉树(-1),对于本身就是一棵完全二叉树,那么这个序列就会是N的元素加上一连串的-1。因此从1中得到的根节点开始层次遍历,如果没有遇到-1,计数加1,且这是当前的最后一个结点;如果遇到了-1说明这是这棵树的子图(到这个结点为止的满足定义的完全二叉树)的结点数,如果等于N则说明是完全二叉树,否则不是。

3. 根据2的情况,输出结果。

注意点:

1. 根节点寻找的方法。如在长度是n的数组中寻找3:find(a,a+n,3)-a

2. 完全二叉树的层次遍历特点

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
struct Node{
	int left,right;
};
int toIndex(string s){
	if(s=="-") return -1;
	int ans = 0;
	for(int i=0;i<s.length();i++){
		ans = ans*10+s[i]-'0';
	}
	return ans;
}
int N;Node node[27];
bool visit[27]={false};
bool levelOrder(int root,int& last){
	queue<int> q;
	q.push(root);
	int cnt = 0;
	while(!q.empty()){
		int top = q.front();
		q.pop();
		if(top!=-1){
			cnt++; 
			last = top;
		}
		else{
			return cnt==N;
		}
		q.push(node[top].left);
		q.push(node[top].right);
	}
}
int main(void){
	string l,r;cin>>N;
	for(int i=0;i<N;i++){
		cin>>l>>r;
		if(l!="-"){
			node[i].left = toIndex(l);
			visit[toIndex(l)]=true;
		}
		else node[i].left=-1;
		if(r!="-"){
			node[i].right = toIndex(r);
			visit[toIndex(r)]=true;
		}
		else node[i].right=-1;
	}
	int root = find(visit,visit+N,false)-visit;//寻找root
	int last = -1;
	bool flag = levelOrder(root,last);
	if(flag) cout<<"YES "<<last<<endl;
	else cout<<"NO "<<root<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值