数组模拟二叉树之P1087 FBI树

来源:互联网 发布:双色球数据分据库 编辑:程序博客网 时间:2024/06/05 04:18

题目描述

我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。

FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:

1) T的根结点为R,其类型与串S的类型相同;

2) 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。

现在给定一个长度为2^N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历序列。

输入输出格式

输入格式:

第一行是一个整数N(0 <= N <= 10),第二行是一个长度为2^N的“01”串。

输出格式:

包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。

输入输出样例 

输入样例#1:
310001011
输出样例#1:
IBFBBBFIBFIIIFF
  • 题解
这是一个完全二叉树,所以完全可以用数组模拟它。一般树的第一个节点下标为1,所以建树或者输出的时候,以1开始。
注意:树一般也就两种写法:
1、传统递归建树的开2N-1即可。
2、按照堆结构非递归建树,要开2^([logN]+1),[]表示取上整。
至于为什么有一说要开4N,其实这也是上述第二种情况,因为2^([logN]+1)在最坏情况下接近4N。
比如N=1024时只用开2048,而N=1025时却需要开4096个节点,为3.99N。
但在大多数情况下远达不到4N,所以建议还是手动计算出使用大小。
#include <bits/stdc++.h>using namespace std;const int maxn=10+1;char s[1<<maxn],t[(1<<maxn)*4+10];char check(int l,int r){    char tag,stand=s[l];    if(stand=='0') tag='B';    else tag='I';    for(int i=l;i<=r;i++)        if(s[i]!=stand) return 'F';    return tag;}void build(int root,int l,int r){    t[root]=check(l,r);    if(l==r) return;    int mid=(l+r)/2;    build(root*2,l,mid);    build(root*2+1,mid+1,r);}void postorder(int root,int _end){    if(root>=_end) return;    postorder(root*2,_end);    postorder(root*2+1,_end);    printf("%c",t[root]);}int main(){    //freopen("input.txt","r",stdin);    int n;    scanf("%d",&n);    scanf("%s",s);    build(1,0,strlen(s)-1);    int _end=1<<(n+1);    postorder(1,_end);    return 0;}


原创粉丝点击