A1110Complete Binary Tree (25分)(完全二叉树)

一、技术总结

  1. 这里有几个点需要注意,一个是完全二叉树的特点。(结点的编号从1开始)假设当前结点的编号为X,其左结点的编号一定是2X,而右结点的编号为2X+1。同时,结点的最大编号数等于结点的数量。
  2. 假设是完全二叉树后,要判断某个结点是否为叶子结点的标志是,该结点的编号X的左子结点编号2X大于结点的总个数n;判断结点是是否为空节点的标志为,该结点的编号X大于结点的总个数n。
  3. 下面来看到该题,题目给出二叉树,要我们判断是否为完全二叉树。我们选择深度搜索dfs,我们设置一个变量maxn,用于记录结点的最大编号。解读一下dfs函数,root是当前结点的编号,如果当前结点的编号大于之前最大maxn,即保存下来,同时使用ans记录该结点的下标,用于后续输出。代表这最后一个结点的下标,前提是如果是安全二叉树。
  4. 然后就是stoi函数,用于把字符串转化为十进制的数字。详情看这篇博客:https://www.cnblogs.com/tsruixi/p/12944470.html
  5. 在一个就是have数组,用来存储,用于判断根结点的位置。如果是根结点,那么在该have数组中下标内容为0,其余不是根结点的内容是1。
  6. 最后判断,如果maxn记录的最大下标等于结点总数,那么为完全二叉树。否则不是,输出root即根结点下标。

二、参考代码

#include<bits/stdc++.h>
using namespace std;
struct node{
	int l, r;
}a[100];
int maxn = -1, ans;
void dfs(int root, int index){
	if(index > maxn){
		maxn = index;
		ans = root;
	}
	if(a[root].l != -1) dfs(a[root].l, 2 * index);
	if(a[root].r != -1) dfs(a[root].r, 2 * index + 1);
}
int main(){
	int n, root = 0;
	int have[100] = {0};
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		string str1, str2;
		cin >> str1 >> str2;
		if(str1 == "-"){
			a[i].l = -1;
		}else{
			a[i].l = stoi(str1);
			have[stoi(str1)] = 1;
		}
		if(str2 == "-"){
			a[i].r = -1;
		}else{
			a[i].r = stoi(str2);
			have[stoi(str2)] = 1;
		}
	}
	while(have[root] != 0) root++;
	dfs(root, 1);
	if(maxn == n){
		printf("YES %d", ans);
	}else{
		printf("NO %d", root);
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/tsruixi/p/12944431.html