原题目: 1110 Complete Binary Tree (25 分).
题意
给出n个结点(0~n-1)的左右孩子,
👉判断这棵树是否是完全二叉树。
分析
- 关键逻辑: 递归出最大的下标值。
①完全二叉树一定把前面的下标填充满——最大的下标值==最大的结点数;
②不完全二叉树中一定有位置是空的,会存在空位,这就导致——最大下标值>最大的结点数。 - 用DFS生成——按完全二叉树将待判二叉树填入后的最大下标值。
知识点
- 完全二叉树与非完全二叉树的区别——按完全二叉树规则填入数组(其实不用真的设置数组,只需DFS得最大下标)后,最大下标与总结点数的关系。
- 通过DFS获得完全二叉树规则下的下标。
CODE
#include <iostream>
using namespace std;
struct node{
int lchild, rchild;
}a[100];
int maxn = -1, ans; //最大下标值
void DFS(int root, int index);
int main()
{
int n, root = 0, have[100] = {0}; //have数组辅助找根结点
cin >> n;
for ( int i=0; i<n; i++ ){
string l, r;
cin >> l >> r;
if ( l=="-" )
a[i].lchild = -1;
else{
a[i].lchild = stoi(l);
have[stoi(l)] = 1;
}
if ( r=="-" )
a[i].rchild = -1;
else{
a[i].rchild = stoi(r);
have[stoi(r)] = 1;
}
}
//找树根
while ( have[root] ) root++;
//判断是否完全二叉树
DFS(root, 1);
if ( maxn==n ) //完全二叉树的每个结点会把下标填满
cout << "YES " << ans;
else
cout << "NO " << root; //非完全二叉树的最大下标值必然大于总结点数
return 0;
}
void DFS(int root, int index){
if ( index>maxn ){
maxn = index; //不断更新最大下标
ans = root; //存最后一个结点的下标
}
if ( a[root].lchild!=-1 ) DFS(a[root].lchild, index*2);
if ( a[root].rchild!=-1 ) DFS(a[root].rchild, index*2+1);
}