告诉你有多少个节点,以及每个节点的权值(权值互不相同),构建出一颗二叉搜索树,且树形为完全二叉树。
因为题目要求树形为完全二叉树,那么知道了节点数n,树形就可以确定了。
先上个图
比如说,n等于8,那么树形肯定就如图中所示。
我把这八个节点用1——8来标号,方法是:根节点标为1,然后对于每个节点来说,如果它自身序号为x,则它的左子节点标为(2*x),右子节点标为(2*x+1)。图中黑色数字就是节点的序号。这样,从序号1遍历到序号n,正好是题目所要求的“level order traversal sequence”。
因为这棵树是二叉搜索树,对每个节点来说,左子树上所有权值都小于自身权值,右子树上所有权值都大于自身权值,所以中序遍历这棵树的时候,得到的就是从小到大权值递增的序列。
所以我把题目给定的权值从小到大排好,放在shu[]数组里,shu[0]就是中序遍历过程中第一个被遍历到的节点的权值,shu[1]就是第二个被遍历到的节点的权值……图中蓝色数字就是节点被遍历的次序。假设该次序为y,则shu[y]就是该节点的权值。
最后输出的时候,从节点1到节点n,输出每个节点的权值即可。
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int shu[1100],n;
int tree[1100];
int level,cnt=1;
//中序遍历这棵树,也就是普通的深搜
void func(int lv,int x){
if(x>n)return;
if(lv>=level){
tree[x]=cnt++;
return;
}
func(lv+1,x*2);
//处理完当前节点
tree[x]=cnt++;
func(lv+1,x*2+1);
}
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&shu[i]);
sort(shu+1,shu+n+1);
//计算n个节点的树有多少层
//如节点数为1,则树高为1;节点数为2或3,则树高为2。节点数在[2^(k-1),2^k-1],树高就为k。
for(level=1;(1<<level)<=n;level++);
func(1,1);
for(i=1;i<=n;i++){
printf("%d",shu[tree[i]]);
if(i<n)printf(" ");
else printf("\n");
}
return 0;
}