Problem Description
题目1078:二叉树遍历
Problem Solutions
思路
由前序遍历可以知道二叉树的根节点
由中序遍历可以将根节点左边划分为左子树,根节点右边划分为右子树
知道了左子树和右子树各自的节点个数之后就可以得到左子树的前序遍历和中序遍历结果以及右子树的前序遍历和中序遍历结果.
这样就就可以将问题规模缩小从而递归解决问题.
在求解过程中需要注意处理子树只有一个节点的情形和子树为空的情形.
比如说前序遍历结果为AG,中序遍历结果为AG,那么左子树为空,这种情况要注意.
MYCode
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 30
char str1[MAX];
char str2[MAX];
struct node
{
int left;
int right;
};
node tree[MAX];
void init()
{
int i;
for(i=0;i<MAX;i++)
{
tree[i].left=-1;
tree[i].right=-1;
}
}
void build(char str1[MAX],char str2[MAX])
{
int len=strlen(str1);
if(len==1||len==0)//叶子节点或者空节点
return;
//cout<<"build "<<str1<<" "<<str2<<endl;
int root_index=str1[0]-'A';
int left_index=str1[1]-'A';
int i,j;
int pos=0;
for(i=0;i<len;i++)
{
//二叉树中所有节点都是字母并且各不相同
if(str2[i]==str1[0])
{
pos=i;
break;
}
}
char left_prefix[MAX],left_mid[MAX],right_prefix[MAX],right_mid[MAX];
int left_len=pos;
int right_len=len-left_len-1;
//获得右子树的根节点
int right_index=str1[left_len+1]-'A';
if(left_len!=0)//左子树是否为空
tree[root_index].left=left_index;
if(right_len!=0)//右子树是否为空
tree[root_index].right=right_index;
for(i=1,j=0;i<=left_len;i++)
left_prefix[j++]=str1[i];
for(i=0,j=0;i<left_len;i++)
left_mid[j++]=str2[i];
left_prefix[j]='\0';
left_mid[j]='\0';
for(i=left_len+1,j=0;i<len;i++)
right_prefix[j++]=str1[i];
for(i=left_len+1,j=0;i<len;i++)
right_mid[j++]=str2[i];
right_prefix[j]='\0';
right_mid[j]='\0';
//cout<<left_prefix<<" "<<left_mid<<" "<<right_prefix<<" "<<right_mid<<endl;
build(left_prefix,left_mid);
build(right_prefix,right_mid);
}
void suffix(int root)
{
if(tree[root].left!=-1)
suffix(tree[root].left);
if(tree[root].right!=-1)
suffix(tree[root].right);
cout<<(char)('A'+root);
}
int main()
{
while(scanf("%s%s",&str1,&str2)!=EOF)
{
init();
int root_index=str1[0]-'A';
build(str1,str2);
suffix(root_index);
cout<<endl;
}
}
解法和代码都不够简洁.如果有更简洁的解法和代码欢迎留言.
测试提交口