洛谷Oj-FBI树-树的后序遍历

来源:互联网 发布:啊哈,算法 豆瓣 编辑:程序博客网 时间:2024/06/06 04:00

问题描述:
我们可以把由“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树,并输出它的后序遍历序列。
AC代码:

int sum[2000];//前缀和char t[100000];//数组开大,因为结点的数目可不止2^nvoid buildtree(int id,int l,int r)//当前结点的索引,字符串数组的左端点l,右端点r{    int v = sum[r] - sum[l - 1];//[l,r]的部分和    if(v == 0)//全0        t[id] = 'B';    else if(v == r - l + 1)//全1,注意r大l小!!!        t[id] = 'I';    else        t[id] = 'F';    if(l == r)//边界        return;    int mid = (l + r) / 2;//二分    buildtree(id * 2,l,mid);//递归构造左子树    buildtree(id * 2 + 1,mid + 1,r);//递归构造右子树}void dfs(int id)//二叉树的后序遍历{    if(t[id] == '\0')//边界        return;    dfs(id * 2);    dfs(id * 2 + 1);    printf("%c",t[id]);}int main(){    int n;    cin >> n;    n = pow(2,n);    for(int i = 1; i <= n; ++i)    {        scanf("%1d",&sum[i]);        sum[i] = sum[i - 1] + sum[i];//求前缀和的骚操作,感觉类似于滚动数组    }    buildtree(1,1,n);//建树    dfs(1);//后序遍历    return 0;}

解决方法:
数据结构的基本操作