【POJ2255】Tree Recovery解题报告 思路 + 数据 +代码

12 篇文章 0 订阅
1 篇文章 0 订阅
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
/*
    Author: YuXun Lu
    Time:23rd/2/2012
    Last Time:About 7 Hours
    Begin Time:Unknown
    End Time:Unknown
    Test Data:
    ABDKQOPENLMCFIGHJ QKPODBNEMLACIFGJH
    输出:
    随便找一个AC过得程序测一下就好
    思路:
    以前序遍历的第一个元素将中序遍历的数组分成两个部分
    [0..root)和(root,len-1]
    有一个当前指针p,从1开始一直到len1-1遍历前序数组。
    p指向当前在中序遍历搜索的元素。
    有一个node数组,保存左右儿子的下标、自己的val在中序遍历数组
    中的位置还有一个val
    Search_Left(int begin,int end,char val)
        t = search(begin,end,val) //在中序数组里搜索当前要搜索的节点
        if( t != -1 ) 找到了
        {
          nodes[end].l = t;
          p++
          //搜索找到的这个节点的左、右儿子,注意,
          Search_Left的end是父节点的位置,
          Search_Right的begin是父节点的位置
          Search_Left(begin,nodes[t].pos,buf1[p]);
          Search_Right(nodes[t].pos,end,buf1[p]);
        }
    Search_Right(int begin,int end,char val)
    {
        t = Search(begin,end,val)
        if ( t != -1)
        {
           nodes[begin].r = t;
           p++;
           search_left(begin,nodes[t].pos,buf1[p]);
           search_right(nodes[t].pos,end,buf1[p]);
        }
    }
    注意,必须先搜左边的再搜右边的
    因为每次搜索的区间都不一样,最好自己构建一棵树写一下这个
    过程,区间的两个端点是有继承性的。
*/
const int MAX_SIZE = 1000;
struct node
{
    int l; // the index of node in node
    int r;
    char val;
    int pos;
};
char buf1[MAX_SIZE];
char buf2[MAX_SIZE];
int len1 = 0 ,len2 = 0,p;
node nodes[MAX_SIZE];
void left_search(int begin,int end,char val);
void right_search(int begin,int end,char val);
int search(int begin,int end,char val);
void DFS(node now)
{
    if(now.l != -1)
      DFS(nodes[now.l]);
    if(now.r != -1)
      DFS(nodes[now.r]);
    printf("%c",now.val);
}
int search1(int begin,int end,char val)
{
    int res = -1;
    for(int i = begin;i < end; i++)
    {
        if ( val == buf1[i])
            res = i;
    }
    return res;
}
void left_search(int begin,int end,char val)
{
    int t;
    if(begin >= end)
        return;
#ifdef DBG
    printf("Search left son for %c\n",nodes[end].val);
#endif
    t = search(begin,end,val);
    if( t != -1)
    {
        ///找到了
#ifdef DBG
    printf("Gotted!Val is %c\n",buf2[t]);
#endif
        nodes[end].l = t;
        p++; ///找下一个元素
        left_search(begin,nodes[t].pos,buf1[p]);
        right_search(nodes[t].pos,end,buf1[p]);
    }
}
void right_search(int begin,int end,char val)
{
    int t;
    if(begin >= end)
     return;
#ifdef DBG
    printf("Search right son for %c\n",nodes[begin].val);
#endif
    t = search(begin,end,val);
    if( t != -1)
    {
#ifdef DBG
    printf("Gotted!The val is %c\n",buf2[t]);
#endif
        nodes[begin].r = t;
        p++;
       // right_search(nodes[t].pos,end,buf1[p]);
        left_search(begin,nodes[t].pos,buf1[p]);
        right_search(nodes[t].pos,end,buf1[p]);
    }
}
int search(int begin,int end,char val)
{
    int res = -1;
    for(int i = begin; i < end; i++)
    {
        if(buf2[i] == val)
        {
            res = i;break;
        }
    }
    return res;
}
int main(int argc,char* argv[])
{
    #ifdef INPUT
        freopen("B:\\acm\\poj2255-Tree Recovery\\input.txt","r",stdin);
    #endif
    while(scanf("%s",buf1) != EOF)
    {
       int root = 0;
        memset(nodes,0,sizeof(node)*MAX_SIZE);
        p = 0;
        scanf("%s",buf2);
        len1 =strlen(buf1);len2 = strlen(buf2);
        for(int i = 0 ; i < len1 ; i++)
        {
            nodes[i].val = buf2[i];
            nodes[i].l = -1;
            nodes[i].r = -1;
            nodes[i].pos = i;
        }
        root = search(0,len2,buf1[0]);


        p = 1;
        left_search(0,root,buf1[p]);
        right_search(root,len2,buf1[p]);
        DFS(nodes[root]);

        memset(buf1,0,sizeof(char)*MAX_SIZE);
        memset(buf2,0,sizeof(char)*MAX_SIZE);
        printf("\n");
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值