将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。
输入格式:
输入第一行给出一个不超过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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码如下:
#include<iostream>
using namespace std;
const int MAXSIZE = 100010;
typedef struct bstnode {
int data;
struct bstnode* lchild, * rchild;
}bstnode,*bstree;
#define OK 1
bstree T=NULL;
int cnt = 0;
bstree createbst(bstree T, int key)
{
if (!T)
{
T = (bstree)malloc(sizeof(bstnode));
T->data = key;
T->lchild=T->rchild=NULL;
}
else if (key < T->data)
{
T->rchild=createbst(T->rchild,key);
}
else {
T->lchild=createbst(T->lchild,key);
}
return T;
}
void levelorder(bstree b)
{
bstree qu[200];//开一个数组充当队列
bstree pri;
int front=0;
int rear=0;
qu[front]=b;
front++;
while (front != rear)
{
pri=qu[rear];
rear++;
cnt++;
if(cnt==1)
{
printf("%d",pri->data);
}
else{
printf(" %d", pri->data);
}
if (pri->lchild != NULL)
{
qu[front++]=pri->lchild;
}
if (pri->rchild != NULL)
{
qu[front++]=pri->rchild;
}
}
}
void judge(bstree T)
{
bstnode* x;
bstnode* can[20];
int front=0;
int rear=0;
int q=0;
can[front++]=T;
while(front!=rear)
{
x=can[rear++];
if(x->lchild!=NULL)
{
can[front++]=x->lchild;
}
if(x->rchild!=NULL)
{
can[front++]=x->rchild;
}
if((!x->lchild)&&x->rchild)
{
cout << "NO";
return ;
}
if((x->lchild&&(!x->rchild))||(!x->lchild&&!x->rchild))
{
q=1;
}
while(q==1 && front!=rear)
{
x=can[rear++];
if(x->lchild || x->rchild)
{
cout << "NO";
return ;
}
}
}
cout << "YES";
}
int main()
{
int n;
cin >> n;
int s = n;
while (s--)
{
int x;
cin >> x;
T=createbst(T, x);
}
levelorder(T);
printf("\n");
judge(T);
return 0;
}
1.注意传入函数的形式和其他地方到底是使用bstnode还是bstree。
2.这道题给出了怎么创建堆,怎么层次遍历一棵树,怎么判断一棵树是不是完全二叉树。
怎么创建堆(也就是二叉搜索树)的思路:
从根节点开始,将关键值(也就是插入的值)key与结点的左孩子和右孩子进行比较,比结点大,插入到左侧,比节点小,插入到右侧。
bstree createbst(bstree T, int key)
{
if (!T)
{
T = (bstree)malloc(sizeof(bstnode));
T->data = key;
T->lchild=T->rchild=NULL;
}
else if (key < T->data)
{
T->rchild=createbst(T->rchild,key);
}
else {
T->lchild=createbst(T->lchild,key);
}
return T;
}
怎么进行层次遍历:
开一个一维数组(队列),数组里面存储的是一个树结点类型的数据。将根插入队列,将根输出,再将根的左右孩子插入队列,以此类推。
void levelorder(bstree b)
{
bstree qu[200];//开一个数组充当队列
bstree pri;
int front=0;
int rear=0;
qu[front]=b;
front++;
while (front != rear)
{
pri=qu[rear];
rear++;
cnt++;
if(cnt==1)
{
printf("%d",pri->data);
}
else{
printf(" %d", pri->data);
}
if (pri->lchild != NULL)
{
qu[front++]=pri->lchild;
}
if (pri->rchild != NULL)
{
qu[front++]=pri->rchild;
}
}
}
怎么判断一棵树是不是完全二叉树:
- 对于任何节点,如果它的左子节点为空,那么它的右子节点也必须为空。
- 如果一个节点是叶节点(即没有子节点),那么后续的所有节点也必须是叶节点。
void judge(bstree T)
{
bstnode* x;
bstnode* can[20];
int front=0;
int rear=0;
int q=0;
can[front++]=T;
while(front!=rear)
{
x=can[rear++];
if(x->lchild!=NULL)
{
can[front++]=x->lchild;
}
if(x->rchild!=NULL)
{
can[front++]=x->rchild;
}
if((!x->lchild)&&x->rchild)
{
cout << "NO";
return ;
}
if((x->lchild&&(!x->rchild))||(!x->lchild&&!x->rchild))
{
q=1;
}
while(q==1 && front!=rear)
{
x=can[rear++];
if(x->lchild || x->rchild)
{
cout << "NO";
return ;
}
}
}
cout << "YES";
}