算法训练 FBI树
时间限制:1.0s 内存限制:256.0MB
锦囊1
二叉树。
问题描述
我们可以把由“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树是一种二叉树,它的结点类型也包括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树,并输出它的后序遍历序列。
输入格式
第一行是一个整数N(0 <= N <= 10),第二行是一个长度为2N的“01”串。
输出格式
包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。
样例输入
3
10001011
10001011
样例输出
IBFBBBFIBFIIIFF
数据规模和约定
对于40%的数据,N <= 2;
对于全部的数据,N <= 10。
注:
[1] 二叉树:二叉树是结点的有限集合,这个集合或为空集,或由一个根结点和两棵不相交的二叉树组成。这两棵不相交的二叉树分别称为这个根结点的左子树和右子树。
[2] 后序遍历:后序遍历是深度优先遍历二叉树的一种方法,它的递归定义是:先后序遍历左子树,再后序遍历右子树,最后访问根。
对于全部的数据,N <= 10。
注:
[1] 二叉树:二叉树是结点的有限集合,这个集合或为空集,或由一个根结点和两棵不相交的二叉树组成。这两棵不相交的二叉树分别称为这个根结点的左子树和右子树。
[2] 后序遍历:后序遍历是深度优先遍历二叉树的一种方法,它的递归定义是:先后序遍历左子树,再后序遍历右子树,最后访问根。
注释:本题就是用到了二叉树。解题时思路清晰、目的明确就好了,主要分以下几个步骤:
1、以字符串的形式录入原始串s;
2、按题意求欲设的01串的长度:pow(2,n);
3、将字符串s转换为01串:全0为B,全1为I,混合串为F;
4、递归创建二叉树;
5、后序遍历二叉树并输出。
1 #include<stdio.h> 2 #include<math.h> 3 #define MAX 10000 4 int num[MAX]; 5 char s[MAX]; 6 //定义结构体 7 struct Node{ 8 Node *left,*right; 9 char c; 10 }; 11 //将字符数组转为整形数组 12 void strtoint(char *s, int *num, int len) { 13 for(int i=0;i<len;i++){ 14 num[i] = s[i] - '0'; 15 } 16 } 17 //后序遍历:递归遍历左右子树 18 void lastdfs(Node *head){ 19 if(head->left) 20 lastdfs(head->left); 21 if(head->right) 22 lastdfs(head->right); 23 printf("%c",head->c); 24 } 25 //判断并返回01串是否为全0、全1、混合串 26 char fbi(int *num,int begin,int end){ 27 int sum=0; 28 for(int i=begin;i<=end;i++) { 29 sum+=num[i]; 30 } 31 if(sum==0) return 'B';//全0串 32 else if(sum==end-begin+1) return 'I';//全1串 33 else return 'F';//混合串 34 } 35 //创建二叉树 36 Node *buildTree(int *num, int begin, int end){ 37 char c = fbi(num,begin,end); 38 Node *p = new Node; 39 p->c = c; 40 if(begin<end){//说明子串不为空 41 int mid = (begin+end)/2; 42 p->left = buildTree(num,begin,mid); 43 p->right = buildTree(num,mid+1,end); 44 }else{//若子串为空,左右子树赋NULL 45 p->left=NULL; 46 p->right=NULL; 47 } 48 return p; 49 } 50 int main(){ 51 int n; 52 scanf("%d",&n); 53 getchar();//处理回车 54 gets(s); 55 int len = pow(2,n);//按题意"01"串的长度为2的n次方 56 strtoint(s,num,len); 57 Node *head = buildTree(num,0,len-1); 58 lastdfs(head); 59 return 0; 60 }