1365:FBI树(fbi)

【算法分析】
设树中结点类型,包含char类型的val成员变量,意为结点的类型,可以是’F’, ‘B’或’I’。
估算该问题可能用到的最大结点数。易知FBI树是满二叉树,FBI串最长有2^N,N最大是10,也就是说这个树的叶子结点最多有 2^10个,整棵树的结点数为 2^0+2^1+...+2^10==2^11-1=2047,数组长度设为2050刚刚好。
设函数createTree,参数为fs。意为:根据FBI串fs来构建一棵二叉树。
FBI串的长度都是2的整数幂,下表从0开始,长度为fs.length()。那么fs.length()/2为中间偏右的位置。左半边下标范围为0~fs.length()/2-1,右半边下标范围为fs.length()/2~fs.length()-1。取子串得到左右子树的FBI串,递归调用本函数根据FBI串生成左右子树。

若左右子树根结点的类型相同,那么这棵树根结点也是这个类型(左右子树根结点的类型如果都是I,那么根结点类型也为’I’;若都是’B’, 根结点类型为’B’)。
若左右子树根结点的类型不同,那么这棵树根结点的类型为’F’。
递归出口为:如果FBI串fs长度为1,那么这个结点是叶子结点。看这个字符串中的唯一的字符来确定这个结点的val。

如果是’1’,那么这个叶子结点的val为’I’。
如果是’0’, 那么这个叶子结点的val为’B’。
得到树后,对这棵树做后序遍历。

【参考代码】

#include <bits/stdc++.h>
using namespace std;
#define N 2050
struct Node
{
	char val;//结点类型,可以是'F', 'B', 或'I' 
	int left, right;
};
Node node[N];//结点池 
int n, p;
string s;
int createTree(string fs)//根据FBI串fs构建二叉树,返回二叉树的根 
{
	int np = ++p;
	if(fs.length() == 1)
	{
		if(fs[0]=='1')
			node[np].val='I';
		else 
			node[np].val='B';
		return np;	
	}
	string ls = fs.substr(0, fs.length()/2), rs = fs.substr(fs.length()/2);
	int lp = createTree(ls), rp = createTree(rs);
	node[np].left = lp, node[np].right = rp;
	if(node[lp].val == node[rp].val)
		node[np].val = node[lp].val;//如果二者相同,那么父节点等于孩子结点 
	else
		node[np].val = 'F';
	return np;
}
void postOrder(int r)
{
	if(r == 0)
		return;
	postOrder(node[r].left);
	postOrder(node[r].right);
	cout << node[r].val;
}
int main()
{
	cin >> n >> s;
	int root = createTree(s);
	postOrder(root);
	return 0;
}

`substr()`是C++中`std::string`类的一个成员函数,用于从字符串中提取子串。其基本语法是`string.substr(pos, len)`,其中`pos`是子串的起始位置,`len`是要提取的子串的长度。

详细解释如下:

  • `pos`(起始位置):这是一个必选参数,表示子串的起始位置。位置从0开始计数。如果`pos`等于字符串的长度,则返回一个空字符串;如果`pos`大于字符串长度,则抛出`out_of_range`异常。
  • `len`(长度):这是一个可选参数,表示要提取的子串的长度。如果省略此参数或设置为`string::npos`,则提取从`pos`开始直到字符串末尾的所有字符。

函数返回一个新的字符串对象,包含指定的子串。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值