题目详情:
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7结尾无空行
输出样例:
Preorder: 4 1 3 2 6 5 7结尾无空行
作者:DS课程组;单位:浙江大学;代码长度限制:16 KB;时间限制:400 ms;内存限制:64 MB
已知中序和后序遍历,求前序遍历。如果是笔算,正常思路就是先从后序遍历倒着读,找到后序结果的最后一个(根),然后可以再中序中找到该节点,分为左右两个部分为左右子树,再重复上述操作。这是一个递归的过程,找到左右子树的时候就可以递归求解了。
我写的一个打印前序函数为:void print_front(int *l,int *m,int p=n-1)
l为后序数组,m为中序数组,p为根结点的位置
下面只要在中序中找到l[p]的位置,然后根据这个位置复制出左边的中序和后序数组L1[n],L2[n],以及右边的R1[n],R2[n].传入递归即可。在这个过程中要注意复制的位置。
Code:
#include<iostream>
using namespace std;
int n;
int find(int *a,int x) //再数组中找x(肯定可以找到)
{
for(int i=0;i<n;i++)
if(a[i]==x) return i;
}
void print_front(int *l,int *m,int p=n-1) //打印前序
{
if(p>=0){
cout<<" "<<l[p];
int r=find(m,l[p]); //中序中找到根节点
int L1[n],R1[n],L2[n],R2[n];
for(int i=0;i<r;i++){ //左边的都是0~r-1
L1[i]=l[i];
L2[i]=m[i];
}
for(int i=r,j=0;i<p;i++,j++){ //右边的两个不一样,分别复制
R1[j]=l[i];
}
for(int i=r+1,j=0;i<=p;i++,j++){
R2[j]=m[i];
}
print_front(L1,L2,r-1); //递归打印
print_front(R1,R2,p-r-1);
}
}
int main()
{
cin>>n;
int last[n],mid[n];
for(int i=0;i<n;i++) cin>>last[i]; //后序
for(int i=0;i<n;i++) cin>>mid[i]; //中序
cout<<"Preorder:";
print_front(last,mid);
return 0;
}结果:

按照这个思路就AC了。我看到dalao用string的性质,直接取子串,就省去了繁琐的数组复制。当然是对于读入后序中序时就是字符串更适用,而本题读的是数。
不过我还是强行用string又写了一个:
#include<iostream>
#include<string>
using namespace std;
void print_front(string l,string m) //l为后序字串,m为中序
{
if(l.size()>0){
int ch=l[l.size()-1]; //找到最后一个
cout<<" "<<ch; //这里输出的是ascll码,字符无意义
int k=m.find(ch);
print_front(l.substr(0,k),m.substr(0,k)); //调用substr直接划分
print_front(l.substr(k,l.size()-k-1),m.substr(k+1));
}
}
int main()
{
int n;
cin>>n;
string last,mid;
for(int i=0;i<n;i++){
int x;
cin>>x;
last.push_back(x); //不管字符是什么,输出只关心ascll码,string只是个工具
}
for(int i=0;i<n;i++){
int x;
cin>>x;
mid.push_back(x);
}
cout<<"Preorder:";
print_front(last,mid);
return 0;
}
结果:
注意:如果给的数据量比较大,不要用字符串处理,毕竟ascll值最大为255.
版权声明:本文为qq_60256199原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。