Vijos 1114 FBI树

描述

我们可以把由“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;
}

posted on 2016-10-13 18:59  月夜下  阅读(173)  评论(0编辑  收藏  举报

导航

"320px">