题目来源:天梯赛
将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。
输入格式:
输入第一行给出一个不超过20的正整数N
;第二行给出N
个互不相同的正整数,其间以空格分隔。
输出格式:
将输入的N
个正整数顺序插入一个初始为空的二叉搜索树。在第一行中输出结果树的层序遍历结果,数字间以1个空格分隔,行的首尾不得有多余空格。第二行输出YES
,如果该树是完全二叉树;否则输出NO
。
输入样例1:
9
38 45 42 24 58 30 67 12 51
输出样例1:
38 45 24 58 42 30 12 67 51
YES
输入样例2:
8
38 24 12 45 58 67 42 51
输出样例2:
38 45 24 58 42 12 67 51
NO
思路:
1. 先按照给定的n个数的序列创建二叉树;(每个结点除了左右指针和数据外增加一个序号num)
2. 使用BFS进行层序遍历,得到层序遍历序列,在遍历的同时给二叉树进行编号,通过判断所有结点的编号是否为1-n(完全二叉树的结点可连续由1到n编号),若有一个结点的序号不满足要求则不是完全二叉树;
//L3-010 是否完全二叉搜索树
#include <iostream>
using namespace std;
#include <algorithm>
#include <queue>
#define N 20
int n,a[N];
typedef struct bt //二叉树
{
int data;
int num; //序号
struct bt* Lchild;
struct bt* Rchild;
}TREE,*LPtree;
LPtree Node(int data) //创建结点
{
LPtree newNode=new TREE;
newNode->data=data;
newNode->Lchild=NULL;
newNode->Rchild=NULL;
return newNode;
}
int k=0;
void createTree(LPtree &T) //常见二叉搜索树
{
T=Node(a[k++]); //创建根
LPtree p=T;
while(k<n)
{
if(a[k]>p->data) //插入左子树
{
if(p->Lchild==NULL)
{
p->Lchild=Node(a[k++]);p=T;
}
else
p=p->Lchild;
}
else //插入右子树
{
if(p->Rchild==NULL)
{
p->Rchild=Node(a[k++]);p=T;
}
else
p=p->Rchild;
}
}
}
string ans; //保存遍历结果
bool flag=true; //是否为完全二叉树
void tra_cen(LPtree T) //层序遍历
{
queue<LPtree> q;
int num=1;
T->num=num; //通过标序号来判断是否为完全二叉树,根结点标1
q.push(T);
while(!q.empty())
{
LPtree x=q.front();q.pop();
if(x->num!=num)
flag=false;
ans+=to_string(x->data)+" ";
if(x->Lchild)
{
q.push(x->Lchild);
x->Lchild->num=x->num*2;
}
if(x->Rchild)
{
q.push(x->Rchild);
x->Rchild->num=x->num*2+1;
}
num++;
}
}
int main()
{
cin>>n;
int i;
for(i=0;i<n;i++)
cin>>a[i];
LPtree T;
createTree(T); //创建树
tra_cen(T); //层序遍历
ans.pop_back(); //舍掉末尾空格
cout<<ans<<endl;
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}