题17.2022寒假天梯赛训练-7-10 是否完全二叉搜索树 (30 分)
一、题目
二、题解
本题的关键在于如何判断完全二叉树–通过层序遍历的操作,将NULL也入队,当pop出一个NULL时,标记,此后若再遍历到非空节点则不是完全二叉树。代码如下
#include <bits/stdc++.h>
using namespace std;
typedef struct Tnode *Position;
typedef Position BinT;
struct Tnode
{
int data;
BinT left;
BinT right;
};
BinT insertNode(int data,BinT BST)
{
if(!BST)
{
BST=new Tnode();
BST->data=data;
BST->left=NULL;
BST->right=NULL;
}
else
{
if(data>BST->data)
{
BST->left=insertNode(data,BST->left);
}
else
{
BST->right=insertNode(data,BST->right);
}
}
return BST;
}
void levelOrderTraversal(BinT BT)
{
BinT T=BT;
queue<BinT> q;
q.push(T);
int flag=1;
while(!q.empty())
{
BinT TempT=q.front();
q.pop();
if(TempT)
{
if(flag>1)
{
putchar(' ');
}
printf("%d",TempT->data);
flag++;
}
if(TempT)
{
q.push(TempT->left);
q.push(TempT->right);
}
}
}
int judgeTree(BinT BT)//基于层序遍历判断
{
BinT T=BT;
queue<BinT> q;
q.push(T);
int flag=1,sign=1;//flag:表示是否为完全二叉树,sign表示是否遍历到了空节点(空洞)
while(!q.empty())
{
BinT TempT=q.front();
q.pop();
if(TempT==NULL)
{
sign=0;//遍历到了空洞则将sign置为0
}
else if(!sign)//如果已经遍历到了空洞了之后还碰到非空节点则不是完全二叉树
{
flag=0;
break;
}
if(TempT)
{
q.push(TempT->left);
q.push(TempT->right);
}
}
if(flag)
{
return 1;
}
else
{
return 0;
}
}
/*
错误判断,3、4、5测试点过不去
int judgeTree(BinT BST)
{
if(!BST)
{
return 1;
}
else
{
if(BST->right!=NULL)
{
if(BST->left==NULL)
{
return 0;
}
else
{
return 1&&judgeTree(BST->left)&&judgeTree(BST->right);
}
}
else
{
return 1&&judgeTree(BST->left);
}
}
}
*/
int main()
{
int N;
cin>>N;
BinT BST=NULL;
for(int i=0; i<N; i++)
{
int data;
scanf("%d",&data);
BST=insertNode(data,BST);
}
levelOrderTraversal(BST);
putchar('\n');
if(judgeTree(BST))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
对于上面代码中错误的判断代码的解释:
我敲错的那一段时间对完全二叉树理解就是右子树空可以,但左子树不能空,然后就有了那个代码,但是却针对不到测试点中的–左子树完全/美,右子树完美/全,为NO。比如下面这样: