我们可以把由“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树,并输出它的后序遍历*2序列。输入格式
第一行是一个整数N(0 ≤ N ≤ 10),第二行是一个长度为2^N的“01”串。输入格式
第一行是一个整数N(0 ≤ N ≤ 10),第二行是一个长度为2^N的“01”串。输入样例
3 10001011输出样例
IBFBBBFIBFIIIFF
用一个字符串储存树,最后后序遍历输出该树。
输入一个N,代表叶子节点有2^N个,总结点有2^(N+1)-1个。
由N最大值为十可以把数组开到2048.
树的编号如图:
不难看出,叶子节点的编号为2^N~2^(N+1)-1...(8~15),
首先对叶子结点编码
int n;
cin >> n;
t = pow(2, n);//叶子节点个数
N = 2 * t - 1;//总结点数
cin >> (tre + t);//tre全局变量字符串,从tre[t]开始输入叶子节点。
for (int i = t; i < 2 * t; i++)
{
if (tre[i] == '0') tre[i] = 'B';//对叶子节点进行编码。
else tre[i] = 'I';
}
编码完成后:
递归构造树
BuildTheTree(1);//表示从根节点递归。
递归代码:
char BuildTheTree(int u)
{
if (u >= t && u <= 2 * t - 1)
{
cout<
代码中的cout<<为调试代码。调试结果为
可以发现每次输出的tre[u]即为我们想要的答案。
这是因为我们想知道该节点的值,必须从左右结点下手,于是从下到上的左右根的顺序刚好是符合后序遍历的规则的。
其递归过程如下:
按照我写的数字顺序看就是整个树构造的递归过程。
过程中返回的顺序就是后序遍历,这个时候输出的话就可以得到答案,可以直接返回值,
储存值可以用来做其他的遍历操作(如先序和中序。)
递归完后就是我们想要的树
如图
for(int i=1;i<=N;i++) cout<
我们顺序输出一下
其实这就是层次遍历
后序遍历代码:
void Travel(int u)
{
if (u > N) return;
Travel(2 * u);
Travel(2 * u + 1);
cout << tre[u];
}
改一下cout的位置就可以有不同的遍历结果啦!
最后完整代码
#include
#include
using namespace std;
int t, N;
char tre[3000];
char BuildTheTree(int u)
{
if (u >= t && u <= 2 * t - 1)
{
//cout< N) return;
Travel(2 * u);
Travel(2 * u + 1);
cout << tre[u];
}
int main()
{
int n;
cin >> n;
t = pow(2, n);//叶子节点个数
N = 2 * t - 1;//总结点数
cin >> (tre + t);//tre全局变量字符串,从tre[t]开始输入叶子节点。
for (int i = t; i < 2 * t; i++)
{
if (tre[i] == '0') tre[i] = 'B';//对叶子节点进行编码。
else tre[i] = 'I';
}
BuildTheTree(1);
Travel(1);
//for(int i=1;i<=N;i++) cout<
发现了更简短的版本(核心是一样的。
P1087 FBI树(C++_递归_构造_树形结构)_ccql的博客-CSDN博客
#include
using namespace std;
char s[1 << 11], temp;
int n;
void print(int i)//传统后序遍历模板
{
if (i >= (1 << (n + 1)))
return;
print(2 * i);
print(2 * i + 1);
cout << s[i];
}
int main()
{
cin >> n;
for (int i = (1 << n); i < (1 << n + 1); i++)
{
cin >> temp;
s[i] = (temp == '1' ? 'I' : 'B');//叶子节点
}
for (int i = (1 << n) - 1; i >= 1; i--)//倒着建树
s[i] = (s[2 * i] == s[2 * i + 1] ? s[2 * i] : 'F');
print(1);
return 0;
}



