根据输入的前序序列和中序序列,判断能否重建二叉树,能则输出后序遍历序列,否则输出“No”。
#include <iostream>
using namespace std;
int node_num = 0;
int pre_tree[1024] = {0};
int in_tree[1024] = {0};
int post_tree[1024] = {0};
bool Rebulid(int pre_start,int pre_end,int in_start,int in_end,int post_start,int post_end)
{
if(pre_end - pre_start != in_end - in_start) //左右子树数量不等
{
return false;
}
int root = pre_tree[pre_start]; //根节点
post_tree[post_end] = root; //后序遍历根节点在最后一个
int i = 0;
for(i = in_start; i <= in_end; ++i) //寻找中序遍历根节点位置
{
if(in_tree[i] == root)
{
break;
}
}
if(i > in_end) //没有找到返回失败
{
return false;
}
int len1 = i - in_start; //左子树长度
int len2 = in_end - i; //右子树长度
bool left_flag = false; //左子树能否重建标记
bool right_flag = false; //右子树能否重建标记
if(len1 == 0) //所有左子树重建完成
{
left_flag = true;
}
else
{
//递归判断左子树能否重建
left_flag = Rebulid(pre_start+1,pre_start+len1,in_start,in_start+len1-1,post_start,post_start+len1-1);
}
if(len2 == 0) //所有右子树重建完成
{
right_flag = true;
}
else
{
//递归判断右子树能否重建
right_flag = Rebulid(pre_start+len1+1,pre_end,in_start+len1+1,in_end,post_start+len1,post_end-1);
}
return (left_flag && right_flag); //左右子树都能重建能返回true
}
int main()
{
int i = 0;
while (cin>>node_num)
{
for(i = 0; i < node_num; ++i)
{
cin >>pre_tree[i];
}
for(i = 0; i < node_num; ++i)
{
cin >>in_tree[i];
}
if(Rebulid(0,node_num-1,0,node_num-1,0,node_num-1))
{
for(i = 0; i < node_num; ++i)
{
cout<<post_tree[i]<<" ";
}
cout<<endl;
}
else
{
cout<<"No"<<endl;
}
}
return 0;
}