FBI树两种解法

【问题描述】
  我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
  FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:

(1)T的根结点为R,其类型与串S的类型相同;
(2)若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历序列。
【输入文件】
输入文件fbi.in的第一行是一个整数N(0<=N<=10),第二行是一个长度为2N的“01”串。
【输出文件】
输出文件fbi.out包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。

【样例输入】

3
10001011

【样例输出】

IBFBBBFIBFIIIFF
【数据规模】
对于40%的数据,N <= 2;
对于全部的数据,N <= 10。

构建二叉树

从上至下,存储当前整棵树的根节点类型,再从中切断递归生成各个左右子树根节点类型,递归边界是二分到当前子树为空


#include <iostream>
using namespace std;

int a[20] = {0,1,0,0,0,1,0,1,1};
int s[20] = {0,1,1,1,1,2,2,3,4};//用于判断某一范围内是哪种节点,在循环的基础上做了一点优化,s[3] - s[1]就能判断3到2范围内是什么值。

struct node{
	char data;
	node *l,*r;
};
void create(node *t,int st,int ed)
{
	int sum = s[ed]-s[st-1];
	if(sum == 0)t->data = 'B';
	else if(sum == ed-st+1)t->data = 'I';
	else t->data = 'F';
	
	if(st==ed)return ;
	
	node *L,*R;
	R = new node;
	L = new node;
	R->l = NULL;	R->r = NULL;
	L->l = NULL;	L->r = NULL;
	t->l = L;	t->r = R;
	create(t->l,st,(st+ed)/2);
	create(t->r,(st+ed)/2+1,ed);
}

void print(node *p)
{
	if(p==NULL)return;
	print(p->l);
	print(p->r);
	cout << p->data;
} 

int main()
{
	node *root;
	root = new node;
	root->l = NULL;
	root->r = NULL;
	
	create(root,1,8);
	print(root);
}



顺序存储二叉树

从下至上依次生成节点,直到根节点

//if(node[k*2]=='B' && node[k*2+1]=='I'|| node[k*2]=='I' && node[k*2+1]=='B'|| node[k*2]=='F' || node[k*2+1]=='F')
#include<bits/stdc++.h>
using namespace std;
int n,m=1;
char node[10000000];
void houxu(int k)
{
	if(k>=2*m) return;
	houxu(k*2);
	houxu(k*2+1);
	cout << node[k];
	
}
int main()
{
	char ch;
	cin>>n;
	for(int i=1;i<=n;i++)m*=2;
	
	for(int i=m;i<=2*m-1;i++)
	{
		cin>>ch;
		if(ch=='0')
		{
			node[i]='B';
		}else
		{
			node[i]='I';
		}
	}
	
	for(int i = 1; i<2*m; i++)
	cout << node[i] <<" ";
	cout <<endl;
	
	for(int k=m-1;k>0;k--)
	{
		//if(node[k*2]=='B' && node[k*2+1]=='I'|| node[k*2]=='I' && node[k*2+1]=='B'|| node[k*2]=='F' || node[k*2+1]=='F')
		if(node[k*2]=='B'&&node[k*2+1]=='B')
		{
			node[k]='B';
		}else if(node[k*2]=='I'&&node[k*2+1]=='I')
		{
			node[k]='I';
		}
		else node[k] = 'F';
	}
	
	houxu(1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值