描述

我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。

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

  1. T的根结点为R,其类型与串S的类型相同;
  2. 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。

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

格式

输入格式

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

输出格式

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

样例1

样例输入1

3

10001011

样例输出1

IBFBBBFIBFIIIFF

限制

每个测试点1s

来源

NOIP2004普及组第三题

<br/ >

<nr/ >

解析:依据题意构造出这棵二叉树,然后后序遍历即可。

#include <iostream>
#include <string>
using namespace std; struct Node{
char val;
Node *l = NULL, *r = NULL;
}; string s; Node* build(const string& s)
{
bool flag0 = false, flag1 = false;
size_t len = s.length();
for(size_t i = 0; i < len; ++i){
if(s[i] == '0')
flag0 = true;
else
flag1 = true;
if(flag0 && flag1)
break;
}
char ch;
if(flag0 && flag1)
ch = 'F';
else if(flag0)
ch = 'B';
else
ch = 'I';
Node *root = new Node;
root->val = ch;
if(len > 1){
if(len&1){
string left = s.substr(0, len/2);
string right = s.substr(len/2+1);
root->l = build(left);
root->r = build(right);
}
else{
string left = s.substr(0, len/2);
string right = s.substr(len/2);
root->l = build(left);
root->r = build(right);
}
}
return root;
} void post_order(Node* root)
{
if(root != NULL){
post_order(root->l);
post_order(root->r);
cout<<root->val;
}
} void destroy(Node* root)
{
if(root->l != NULL)
destroy(root->l);
if(root->r != NULL)
destroy(root->r);
delete root;
} int main()
{
int n;
cin>>n>>s;
Node *root = build(s);
post_order(root);
destroy(root);
return 0;
}

<br/ >

<br/ >

顺便给出先序和中序遍历:

void pre_order(Node* root)
{
if(root != NULL){
cout<<root->val;
pre_order(root->l);
pre_order(root->r);
}
}
void in_order(Node* root)
{
if(root != NULL){
in_order(root->l);
cout<<root->val;
in_order(root->r);
}
}

<br/ >

以及它们的非递归实现:

#include <iostream>
#include <string>
using namespace std; struct Node{
char val;
Node *l = NULL, *r = NULL, *p = NULL; //增加了一个字段p,用于记录他的父结点
}; string s; Node* build(const string& s, Node* p) //建树也做相应的更改
{
bool flag0 = false, flag1 = false;
size_t len = s.length();
for(size_t i = 0; i < len; ++i){
if(s[i] == '0')
flag0 = true;
else
flag1 = true;
if(flag0 && flag1)
break;
}
char ch;
if(flag0 && flag1)
ch = 'F';
else if(flag0)
ch = 'B';
else
ch = 'I';
Node *root = new Node;
root->val = ch;
root->p = p;
if(len > 1){
if(len&1){
string left = s.substr(0, len/2);
string right = s.substr(len/2+1);
root->l = build(left, root);
root->r = build(right, root);
}
else{
string left = s.substr(0, len/2);
string right = s.substr(len/2);
root->l = build(left, root);
root->r = build(right, root);
}
}
return root;
} void pre_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
cout<<node->val;
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
else if(pre == node->r){
pre = node;
node = node->p;
}
}
} void in_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
cout<<node->val;
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
cout<<node->val;
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
else if(pre == node->r){
pre = node;
node = node->p;
}
}
} void post_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
cout<<node->val;
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
cout<<node->val;
pre = node;
node = node->p;
}
}
else if(pre == node->r){
cout<<node->val;
pre = node;
node = node->p;
}
}
} void destroy(Node* root)
{
if(root->l != NULL)
destroy(root->l);
if(root->r != NULL)
destroy(root->r);
delete root;
} int main()
{
int n;
cin>>n>>s;
Node *root = build(s, NULL);
pre_order(root);
cout<<endl;
pre_order2(root);
cout<<endl<<endl; in_order(root);
cout<<endl;
in_order2(root);
cout<<endl<<endl; post_order(root);
cout<<endl;
post_order2(root);
cout<<endl<<endl; destroy(root);
return 0;
}

Vijos 1114 FBI树的更多相关文章

  1. 【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)

    题目链接: https://vijos.org/p/1114 题目大意: 把01串一分为二,左半边描述当前节点左子树,右半边描述右子树,子树全为1则为I节点,全为0则为B节点,混合则为F节点,直到当前 ...

  2. Vijos P1114 FBI树【DFS模拟,二叉树入门】

    描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种 ...

  3. 创建FBI树

    需求:数串由2^n个'0' '1'数串组成,对于一个数串,有01混合出现,则视为F,全0数串为B,全1数串为I. 将给定数串进行切割,如10010011可以用二叉树表示为 F(10010011) / ...

  4. 蓝桥杯之FBI树问题

    问题描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含"0&q ...

  5. noip普及组2004 FBI树

    FBI树 描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含" ...

  6. [题解]ybt1365:FBI树(fbi)

    ybt1365:FBI树(fbi) [题目描述] 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它 ...

  7. FBI树-数据结构(二叉树)

    问题 B: [2004_p4]FBI树-数据结构 时间限制: 1 Sec  内存限制: 125 MB提交: 57  解决: 46 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称 ...

  8. C语言 · FBI树

    算法训练 FBI树   时间限制:1.0s   内存限制:256.0MB        锦囊1 二叉树. 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I ...

  9. FBI树(第一次做建树题)

    试题来源 NOIP2004 普及组 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它的结 ...

随机推荐

  1. 【C++基础】 类中static private public protected

    静态成员在一个类的所有实例间共享数据 “类属性”,是描述类的所有对象共同特征的一个数据项,对所有对象,它的值相同,static定义,为整个类所共有.相对于“实例属性” 如果static成员是私有类型, ...

  2. ubantu安装jdk来配置hadoop

    1.将jdk-7u5-linux-x64.tar.gz拷贝到/usr/lib/jdk/目录下面,这里如果没有jdk文件夹,则创建该文件夹,命令: sudo mkdir jdk //创建文件夹jdk s ...

  3. Javascript的9张思维导图学习

    思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又极其有效,是一种革命性的思维工具.思维导图运用图文并重的技巧,把各级主题的关系用相互隶属与相关的层级图表现出来 ...

  4. 为什么Android 3.0如此罕见?

    3.0(2011年2月)代号蜂巢,专用于android系统的平板电脑,不用于手机.4.0(2011年5月公布)的开发就是让平板电脑和手机能够共用一个版本的系统.4.0通用于平板电脑和手机.

  5. YUM详解

    用YUM升级软件打开终端,切换到root用户,yum的操作大都须有超级用户的权限.首 先,yum update,这一步是必须的,yum会从服务器的header目录下载rpm的header,放在本地的缓 ...

  6. 欧拉工程第57题:Square root convergents

    题目链接 Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; impo ...

  7. 【Linux高频命令专题(7)】rm

    简述 rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变. 命令格式 rm [选项 ...

  8. C++:概述

    1.基本的输入输出,使用cin>>输入输入.使用cout<<输出 #include<iostream> using namespace std; int main( ...

  9. redhat 7.2 配置yum源

    http://blog.csdn.net/wylfengyujiancheng/article/details/50418930

  10. Java API —— TreeSet类

    1.TreeSet类    1)TreeSet类概述         使用元素的自然顺序对元素进行排序         或者根据创建 set 时提供的 Comparator 进行排序          ...