现在的位置: 首页 > 综合 > 正文

POJ 2255 Tree Recovery

2019年08月14日 ⁄ 综合 ⁄ 共 1335字 ⁄ 字号 评论关闭

          发现自己懒得思考,不能一直刷一眼就看出结果的水题吧?

           思路:

           根据二叉树前中后序遍历的特性

                 

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

抱歉!评论已关闭.