FBI树
题目描述
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。FBI树是一种二叉树,它的结点类型也包括FF结点,BB结点和I结点三种。由一个长度为 2 ^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
- T的根结点为R,其类型与串S的类型相同;
- 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2^N 的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历序列。
输入格式
第一行是一个整数N(0≤N≤10),
第二行是一个长度为2^N的“01”串。
输出格式
一个字符串,即FBI树的后序遍历序列。
输入
3
10001011
输出
IBFBBBFIBFIIIFF
#include<iostream>
#include<math.h>
#include<cstdio>
#include<cstdlib>
using namespace std;
int n;
string str;
struct TreeNode{
char data;
TreeNode* left;
TreeNode* right;
TreeNode(char data):data(data),left(NULL),right(NULL){}
};
TreeNode* Tree[100000];
int p=0;
TreeNode* CreatTree(int Start,int End){
string s=str.substr(Start,End-Start+1);
//cout<<s<<endl;
TreeNode* T=(TreeNode*)malloc(sizeof(TreeNode*));//为了防止指针被覆盖
if(s.find("0")!=string::npos&&s.find("1")!=string::npos){
//cout<<"P:"<<p<<" "<<"F"<<endl;
Tree[p]=new TreeNode('F');
T=Tree[p];
}
else if(s.find("0")!=string::npos&&s.find("1")==string::npos){
//cout<<"P:"<<p<<"B"<<endl;
Tree[p]=new TreeNode('B');
T=Tree[p];
}
else if(s.find("0")==string::npos&&s.find("1")!=string::npos){
//cout<<"P:"<<p<<"I"<<endl;
Tree[p]=new TreeNode('I');
T=Tree[p];
}
p++;
if(s.size()==1){
return T;
}
else{
T->left=CreatTree(Start,Start+(End-Start)/2);
T->right=CreatTree(End-(End-Start)/2,End);
}
return T;
}
void PostOrder(TreeNode* root){
if(root==NULL) return ;
PostOrder(root->left);
PostOrder(root->right);
cout<<root->data;
}
int main(){
cin>>n;
for(int i=1;i<=pow(2,n);i++){
char c;
cin>>c;
str=str+c;
}
//cout<<str<<endl;
TreeNode* root=CreatTree(0,str.size()-1);
PostOrder(Tree[0]);
}
求先序排列
题目描述
给出一棵二叉树的中序与后序排列,求出它的先序排列,(约定树结点用不同的大写字母表示,长度≤8)。
输入格式
2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
1行,表示一棵二叉树的先序。
输入
BADC
BDCA
输出
ABCD
#include<iostream>
#include<string>
using namespace std;
string in;
string post;
struct TreeNode{
char data;
TreeNode* left;
TreeNode* right;
TreeNode(char data):data(data),left(NULL),right(NULL){}
};
TreeNode* Tree[10000];
TreeNode* CreatTree(int s1,int t1,int s2,int t2){
char c=post[t1];//后序的最后一个
if(s1==t1){//叶子结点
Tree[c-'A']=new TreeNode(c);
return Tree[c-'A'];
}
Tree[c-'A']=new TreeNode(c);
int pos=in.find(c);//在中序中找到对应的顶点以及左右长度
int llen=pos-s2;
int rlen=t2-pos;
//别忘了判左右长度
if(llen) Tree[c-'A']->left=CreatTree(s1,s1+llen-1,s2,s2+llen-1);
if(rlen) Tree[c-'A']->right=CreatTree(s1+llen,t1-1,s2+llen+1,t2);
return Tree[c-'A'];
}
void PreOrder(TreeNode* root){
if(root==NULL) return ;
cout<<root->data;
PreOrder(root->left);
PreOrder(root->right);
}
int main(){
cin>>in>>post;
TreeNode* root=CreatTree(0,post.size()-1,0,in.size()-1);
PreOrder(root);
}
新二叉树
题目描述
输入一串二叉树,输出其前序遍历。
输入格式
第一行为二叉树的节点数 n。(1≤n≤26)
后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。空节点用 * 表示
输出格式
二叉树的前序遍历。
输入
6
abc
bdi
cj*
d**
i**
j**
输出
abdicj
#include<iostream>
using namespace std;
int n;
struct TreeNode{
char data;
TreeNode* left;
TreeNode* right;
TreeNode(char data):data(data),left(NULL),right(NULL){};
};
TreeNode* Tree[10000];
void PreOrder(TreeNode* root){
if(root==NULL) return ;
cout<<root->data;
PreOrder(root->left);
PreOrder(root->right);
}
int main(){
cin>>n;
string s;
char T=0; int i=n;//因为Tree[0]不一定是根结点!!!!
while(n--){
cin>>s;
if(i==n+1) T=s[0];//记录根结点
//别忘了每一个结点都要判断是否已经存在
if(!Tree[s[0]-'a']) Tree[s[0]-'a']=new TreeNode(s[0]);
if(s[1]!='*'){
if(!Tree[s[1]-'a']) Tree[s[1]-'a']=new TreeNode(s[1]);
Tree[s[0]-'a']->left=Tree[s[1]-'a'];
}
if(s[2]!='*'){
if(!Tree[s[2]-'a']) Tree[s[2]-'a']=new TreeNode(s[2]);
Tree[s[0]-'a']->right=Tree[s[2]-'a'];
}
}
PreOrder(Tree[T-'a']);
}
来源:CSDN
作者:淅淅沥沥的熙
链接:https://blog.csdn.net/qq_38440882/article/details/104683845