POJ 2255 Tree Recovery
发现自己懒得思考,不能一直刷一眼就看出结果的水题吧?
思路:
根据二叉树前中后序遍历的特性
1、前序遍历的第一个字母必是 根
2、在中序遍历的字母串中找出 根字母,那么根字母左右两边的字符串就分别是它的左、右子树
3、利用递归复原二叉树(把子树看作新的二叉树)
4、后序遍历特征:后序遍历字母串 自右至左 依次为:
最外层(总树,设为第0层)右子树的根,内1层右子树的根,内2层右子树的根….内n层右子树的根,内n层左子树的根,内n-1层左子树的根……内1层左子树的根,最外层(总树,第0层)左子树的根。把总树的左子树作为新的总树,继续递归即可。 (注意:总树的叶就是作为“单叶”这棵树本身的右根)
5、输出后序遍历时,只需按4的顺序从左到右排列,再倒置输出即可
#include<iostream>
#include<cstring>
using namespace std;
char post[26];
int point = 0;
void right_to_left(char preo[],char inor[])
{
post[point++] = preo[0];
const int length = strlen(inor);
if(length == 1)
return ;
int j = 0;
for(;j<length;j++)
if(inor[j] == preo[0])
break;
const int flag = j;
int i = ++j;
char inor_temp[26],preo_temp[26];
bool tag = false;//tag标记时代、否有左or右子树
for(j=0;i<length;++i,++j)
{
inor_temp[j] = inor[i];
tag = true;
}
if(tag)
{
inor_temp[j] = '\0';
for(i = 0,j=length-j;j<length;++i,++j)
preo_temp[i] = preo[j];
preo_temp[i] = '\0';//加上字符串结束标志,不然下一次调用strlen()函数将不能成功返回长度
right_to_left(preo_temp,inor_temp);
}
tag = false;
for(i = 0;i<flag;i++)
{
inor_temp[i] = inor[i];
tag = true;
}
if(tag)
{
inor_temp[i] = '\0' ;
for(i=0,j=1;i<flag;++i,++j)
{
preo_temp[i] = preo[j];
}
preo_temp[i] = '\0';
right_to_left(preo_temp,inor_temp);
}
return ;
}
int main(void)
{
char preo[26],inor[26];
while(cin>>preo>>inor)
{
right_to_left(preo,inor);
for(int i=--point;i>=0;i--)
printf("%c",post[i]);
printf("\n");
}
return 0;
}
转自:
優YoU http://user.qzone.qq.com/289065406/blog/1299063032

浙公网安备 33010602011771号