joj1317

来源:互联网 发布:易语言彩票倒计时源码 编辑:程序博客网 时间:2024/05/02 20:55

#include <iostream>
#include <string>
using namespace std;
char stack[30];//用栈依次将右孩子入栈,实现树后序遍历序列的存放
int top;
void Recovery_Tree(string pre,string in) //重新构造二叉树
{
 int len_pre=pre.length();
 int index;  //每次记录的是当前递归序列根结点在中序遍历串中的位置
 string in_left_str,in_right_str,pre_left_str,pre_right_str;
 if(len_pre>0)
 {
  stack[top++]=pre[0]; //此处进栈的顺序是“根”“右”“左”只需在输出的时候反向输出即可;
    //注意此处除开stack外其他变量都会是函数的临时变量;                     //根在前序遍历串中的位置始终是在串第一个字符,也就是下标是0的位置
  index=in.find(pre[0]);  //寻找当前根节点在中序遍历结果的索引位置
  in_left_str=in.substr(0,index); //中序遍历结果的左字串
  in_right_str=in.substr(index+1);//中序遍历结果的右字串
  pre_left_str=pre.substr(1,index);//前序遍历结果的左字串
  pre_right_str=pre.substr(index+1);//前序遍历结果的右字串
  Recovery_Tree(pre_right_str,in_right_str); //此处一定要细心
  Recovery_Tree(pre_left_str,in_left_str);
 }
}
int main()
{
 string str1,str2;
 while(cin>>str1>>str2)
 {
  top=0;
  Recovery_Tree(str1,str2);
  for(top--;top>=0;top--)
   cout<<stack[top];
  cout<<endl;
 }
 return 0;
}
// 根据前序遍历的特点, 知前序序列(Pre)的首个元素(Pre[0])为根(root), 
//然后在中序序列(In)中查找此根(Pre[0]),  根据中序遍历特点, 知在查找到的根(root) 前边的序列为左子树, 
//后边的序列为右子树。 设根前边有left个元素.. 则又有, 在前序序列中,
//紧跟着根(root)的left个元素序列(即Pre[1...left]) 为左子树,
//在后边的为右子树..而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为Pre[1...left]),
//中序序列为In[0...left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。


//刘汝佳版
#include<iostream>
#include<string.h>
using namespace std;
char s1[30],s2[30],ans[30];

void build(int n,char* s1,char* s2,char* ss){
     if(n<=0) return;
     int p=strchr(s2,s1[0])-s2;//strchr的用法经典!!! p为根在中序遍历中的位置!!!
     build(p,s1+1,s2,ss);
     build(n-p-1,s1+p+1,s2+p+1,ss+p);//分别构造左右子树的后续遍历!!!
     ss[n-1]=s1[0];//把根节点添加到末尾!!注意到ss的重要性,因为n是变化的!!!
     }
    
int main(){
    while(scanf("%s%s",s1,s2)==2){
       int n=strlen(s1);
       build(n,s1,s2,ans);
       ans[n]='/0';
       cout<<ans<<endl;
    }
    return 0;}