题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2040点击打开链接
二叉树的遍历 | ||||||
| ||||||
Description | ||||||
给出一棵二叉树的中序和前序遍历,输出它的后序遍历。 | ||||||
Input | ||||||
本题有多组数据,输入处理到文件结束。 每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点。 接下来的一行每行包括n个整数,表示这棵树的中序遍历。 接下来的一行每行包括n个整数,表示这棵树的前序遍历。 3<= n <= 100 | ||||||
Output | ||||||
每组输出包括一行,表示这棵树的后序遍历。 | ||||||
Sample Input | ||||||
7 4 2 5 1 6 3 7 1 2 4 5 3 6 7
| ||||||
Sample Output | ||||||
4 5 2 6 7 3 1 | ||||||
Source | ||||||
2014 Winter Holiday Contest 5 | ||||||
Author | ||||||
TwIStOy |
首先需要知道前序遍历、中序遍历和后序遍历之间的关系 以及他们的遍历方法
前序遍历的第一个为树根
再观察中序遍历 确认根的位置
然后中序遍历中根的左边为左子树,右边为右子树
然后将两棵树看做新的树
递归判断
如果不够清楚可以翻一翻《挑战程序设计竞赛2》
里面有很巧妙地代码
下面的加入了建树的过程 方法与书中代码相同
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <limits>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
int n=0;
struct tree
{
int val;
struct tree* l;
struct tree* r;
};
vector<int > pre;
vector<int > in;
int ii=0;
tree * after(int l,int r)
{
if(l>=r)
return NULL;
tree *mid = new tree;
mid->val=pre[ii++];
int m=(find(in.begin(),in.end(),mid->val)-in.begin());
mid->l=after(l,m);
mid->r=after(m+1,r);
return mid;
}
void show(tree* root)
{
if(root==NULL)
return ;
show(root->l);
show(root->r);
printf("%d ",root->val);
}
int main()
{
int n,k;
while(cin >> n)
{
for(int i=0;i<n;i++)
{
cin >> k;
in.push_back(k);
}
for(int i=0;i<n;i++)
{
cin >> k;
pre.push_back(k);
}
tree* root=after(0,n);
show(root);
cout << endl;
}
}
如果给出条件为中序遍历和后序遍历 则类比前序遍历和中序遍历可以找到规律
后序遍历最后一个为根节点 然后通过中序遍历判断左右子树
注意后序遍历先算右子树
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <limits>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
int n=0;
struct tree
{
int val;
struct tree* l;
struct tree* r;
};
vector<int > post;
vector<int > in;
int ii=n;
tree* after(int l,int r)
{
if(l>=r)
return NULL;
tree *mid = new tree;
mid->val=post[ii--];
int m=(find(in.begin(),in.end(),mid->val)-in.begin());
mid->r=after(m+1,r);
mid->l=after(l,m);
return mid;
}
void show(tree* root)
{
if(root==NULL)
return ;
printf("%d ",root->val);
show(root->l);
show(root->r);
}
int main()
{
int n,k;
while(cin >> n)
{
ii=n-1;
for(int i=0;i<n;i++)
{
cin >> k;
in.push_back(k);
}
for(int i=0;i<n;i++)
{
cin >> k;
post.push_back(k);
}
tree* root=after(0,n);
show(root);
cout << endl;
}
}