注意静态二叉树读入的方式,scanf()容易出错
法1:bfs按层遍历一遍,判断元素是否连续
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct node
{
int lchild,rchild;
};
vector<node> T;
int num[21];
int after=1,isComplete=1;
int last=-1;
void isCBT(int root){
if(root==-1) return;
queue<int> q;
q.push(root);
last=root;
while(!q.empty()){
int tmp=q.front();
q.pop();
last=tmp;
if(T[tmp].lchild!=20){
if(after==0) isComplete=0;
q.push(T[tmp].lchild);
}else{
after=0;
}
if(T[tmp].rchild!=20){
if(after==0) isComplete=0;
q.push(T[tmp].rchild);
}else{
after=0;
}
}
}
int main(){
int n,root;
scanf("%d",&n);
T.resize(n);
string t1,t2;
for(int i=0;i<n;i++){
cin>>t1>>t2;
T[i].lchild=((t1=="-")?20:stoi(t1));
T[i].rchild=((t2=="-")?20:stoi(t2));
num[T[i].lchild]=1;
num[T[i].rchild]=1;
}
for(int i=0;i<n;i++){
if(num[i]==0){
root=i;
break;
}
}
isCBT(root);
if(isComplete){
printf("YES %d",last);
}else{
printf("NO %d",root);
}
return 0;
}
法2:
完全二叉树一定把前面的下标充满: 最大的下标值 == 最大的节点数;
不完全二叉树前面一定有位置是空,会往后挤: 最大的下标值 > 最大的节点数
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
struct node
{
int lchild,rchild;
};
vector<node> T;
int num[20];
int max_index=-1,ans;
void dfs(int root,int index){
if(root==-1) return;
if(index>max_index){
max_index=index;
ans=root;
}
dfs(T[root].lchild,index*2+1);
dfs(T[root].rchild,index*2+2);
}
int main(){
int n;
scanf("%d",&n);
T.resize(n);
string t1,t2;
for(int i=0;i<n;i++){
cin>>t1>>t2;
if(t1=="-"){
T[i].lchild=-1;
}else{
T[i].lchild=stoi(t1);
num[T[i].lchild]=1;
}
if(t2=="-"){
T[i].rchild=-1;
}else{
T[i].rchild=stoi(t2);
num[T[i].rchild]=1;
}
}
int root=0;
while(num[root]==1) root++;
dfs(root,0);
if(max_index==(n-1)){
printf("YES %d",ans);//注意index不一定等于ans啊~~,因为根不一定从0开始,后面的结点也不是按顺序排列的~
}else{
printf("NO %d",root);
}
return 0;
}