【SOJ 1822】二叉树

做了这么久的测试,终于有一套比较简单的题了(激动)

【题目】

题目描述:

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(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 为右儿子这种方式来建树的话,极端数据下有(2^{0} + 2^{1} + …… + 2^{19})个节点,也就是(2^{20} - 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;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/81254012