当前位置 博文首页 > 一位初中编程爱好者的博客:1365:FBI树(fbi)

    一位初中编程爱好者的博客:1365:FBI树(fbi)

    作者:[db:作者] 时间:2021-08-29 22:26

    题目

    1365:FBI树(fbi)

    时间限制: 1000 ms 内存限制: 65536 KB【题目描述】
    我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。

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

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

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

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

    【输入】
    第一行是一个整数N(0≤N≤10),第二行是一个长度为2N的“01”串。

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

    【输入样例】
    3
    10001011
    【输出样例】
    IBFBBBFIBFIIIFF
    【提示】
    FBI树
    对于40%的数据,N≤2;
    对于100%的数据,N≤10。


    题目分析:我们可以按照要求建树,并自底向上初始化,最后后序遍历。


    C++代码

    #include<iostream>
    using namespace std;
    int i = 0;//使用全局变量记录字符串下标,不推荐这种写法,建议写到一个类里
    struct Node
    {
    	char value;
    	Node* leftChild;
    	Node* rightChild;
    };
    void createFBT(int d, Node*& root, string str)
    {
    	root = new Node;
    	if (d > 1)
    	{
    		createFBT(d - 1, root->leftChild, str);
    		createFBT(d - 1, root->rightChild, str);
    		if (root->leftChild->value != root->rightChild->value || root->leftChild->value == 'F')
    			root->value = 'F';
    		else
    			root->value = root->leftChild->value;
    	}
    	else
    	{
    		root->value = str[i++] == '0' ? 'B' : 'I';
    		root->leftChild = root->rightChild = nullptr;
    	}
    }
    void postorder(Node* root)
    {
    	if (root)
    	{
    		postorder(root->leftChild);
    		postorder(root->rightChild);
    		cout << root->value;
    	}
    }
    void deleteFBT(Node*& root)
    {
    	if (root->leftChild)
    	{
    		deleteFBT(root->leftChild);
    		deleteFBT(root->rightChild);
    	}
    	delete root;
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	int n;
    	string str;
    	cin >> n >> str;
    	Node* root;
    	createFBT(n + 1, root, str);
    	postorder(root);
    	deleteFBT(root);
    	return 0;
    }
    
    cs