一道清华的上机题目

同学让我帮写的,还写了好多注释,丢掉可惜了,发上来吧。。呵呵 

试题三(8个测试数据,每个5分,共40分)
 二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
变量条件:二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。
运行时限:1秒/测试数据。
输入格式:两行,第一行为前序遍历,第二行为中序遍历。
输出格式:若不能根据前序和中序遍历求出后序遍历,输出NO ANSWER;否则输出一行,为后序遍历。
可执行文件:program3.exe

样例一:
Input.txt ABC BAC  Output.txt BCA 
样例二:
Input.txt FDXEAG XDEFAG  Output.txt XEDGAF 
样例三:
Input.txt ABCD BDAC  Output.txt NO ANSWER 

// writen by sunboy
// 07.07.28 
/*
 基本思想 :
  对于字符串先序:pre=“FDXEAG” 中序:mid=“XDEFAG”,要求后序rear; 
  先在中序中找到找到pre[0];从这个位置将mid分为nmid1和nmid2
   在这里分别为nmid1="XDE";nmid2="AG";从pre串中可以得到npre1="DXE";
   npre2="AG";
   rear=nrear1+nrear2+pre[0];
*/

#include 
< iostream >
#include 
< string >
using   namespace  std;
string  prestr,midstr,rearstr;
int  flag = 0 ; // 0:可以求得后序 1:输出错误 
string  Calrear( string  pre, string  mid) // 返回前序为pre,中序为mid字符串的后序 
{
    
string ch="";
    ch
+=pre[0];
    
string npre1="",npre2="",nmid1="",nmid2="";
    
int i,j;
    
int len1=pre.length();
    
int len2=mid.length();
    
if(len1!=len2) {flag=1;return npre1;} //出现错误,找不到后序退出 
    if(len1==1||len1==0)
      
{
            
if(pre==mid) 
                
return pre;             //递归终止条件 
            else { flag=1;return pre;} //出现错误,找不到后序退出 
       }

    i
=mid.find(ch);                    //查找pre[0]在mid中的位置 
    nmid1=mid.substr(0,i);              //求nmid1 
    nmid2=mid.substr(i+1);               //求nmid2 
    npre1=pre.substr(1,i);              //求npre1 
    npre2=pre.substr(i+1);              //求npre2 
    return Calrear(npre1,nmid1)+Calrear(npre2,nmid2)+ch;   //rear=nrear1+nrear2+pre[0];   
}

int  main()
{
    cin
>>prestr>>midstr;
    rearstr
=Calrear(prestr,midstr);
    
if(flag)
       cout
<<"NO ANSWER"<<endl;
    
else cout<<rearstr<<endl;
    cin
>>rearstr;
    
return 0;
}

题目很简单就是一个递归实现的过程,把握好终止条件就行了。。。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值