做了这么久的测试,终于有一套比较简单的题了(激动)
【题目】
题目描述:
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
完全二叉树:只有最下面的两层结点度能够小于 2 ,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。
上图中,(a)和(b)是完全二叉树,(c)和(d)是非完全二叉树。
给出 N 个数,且这 N 个数构成 1 至 N 的排列。现在需要你按顺序构建一棵二叉排序树,并按照层次遍历的方式输出它,然后判断它是否是一棵完全二叉树。
输入格式:
输入包含两行:
第一行为一个正整数 N ;
第二行为 1 至 N 的排列。
输出格式:
输出包含两行:
第一行为构建出的二叉排序树的层次遍历;
第二行判断是否是完全二叉树:若是输出“yes”,否则输出“no”。
样例数据:
输入
10
7 9 8 4 6 2 10 1 5 3输出
7 4 9 2 6 8 10 1 3 5
yes
输入
5
3 4 5 2 1输出
3 2 4 1 5
no
备注:
【样例1说明】
【样例2说明】
【数据规模与约定】
对于 100% 的数据,1 ≤ N ≤ 20。
【分析】
emmm……第一题应该可以叫做水题吧
具体也就是按照题目的要求模拟一下就行了
一个小技巧:记录一下这颗二叉树中最大的节点编号 maxn,若 maxn 等于 n 的话才是完全二叉树
这里有一点要注意,若以 root * 2 为左儿子,root * 2 + 1 为右儿子这种方式来建树的话,极端数据下有( + + …… + )个节点,也就是( - 1)个节点,所以说数组要开大一点
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 2000005
using namespace std;
int maxn=0,a[N],tree[N];
void add(int root,int x)
{
maxn=max(maxn,root);
if(!tree[root])
{
tree[root]=x;
return;
}
if(x<tree[root]) add(root<<1,x);
if(x>tree[root]) add(root<<1|1,x);
}
int main()
{
// freopen("binary.in","r",stdin);
// freopen("binary.out","w",stdout);
int n,i,root=1;
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&a[i]);
tree[1]=a[1];
for(i=2;i<=n;++i)
add(root,a[i]);
for(i=1;i<=maxn;++i)
if(tree[i])
printf("%d ",tree[i]);
printf("\n");
if(maxn>n) printf("no");
else printf("yes");
// fclose(stdin);
// fclose(stdout);
return 0;
}