栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

18723 FBI树(存储建树思路)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

18723 FBI树(存储建树思路)

其实每个结点的值都可以直接由左右结点的值直接得出,可以减少一些遍历的时间。 Description
我们可以把由“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;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966431.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号