之前学习了二叉树的建立(非常模拟),今天写到一道题目,知道前序中序求后序,也就是二叉树的重建
题干
ZCMU-4931
4931: 二叉树遍历
Time Limit: 1 Sec Memory Limit: 32 MB
Submit: 82 Solved: 60
[Submit][Status][Web Board]
Description
二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
Input
两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C…最多26个结点。
Output
输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。
Sample Input
ABC
CBA
ABCDEFG
DCBAEFG
Sample Output
CBA
DCBGFEA
算法解释
采用了别人博客的图,觉得写的还是很清晰的
https://blog.csdn.net/qq_33951180/article/details/72790549#commentBox
现在我们来一组样例
很显然我们看图可以求出以下:
前序 1 2 4 7 3 5 6 8
中序 4 7 2 1 5 3 8 6
根据定理,知道前序和中序可以求出后序,我们这样来实现二叉树的重建
我们知道前序的存储方案是 root->left->right
所以第一个节点一定是总的root,接下来我们在中序中寻找root,由于中序的建立方式是left-> root->right,因此root左侧就是root的左子树,右侧是root的右侧树。
接下来采用递归就可以得到答案了。
我们来用代码实现吧!
AC代码
#include<string>
#include<iomanip>
#include<iostream>
#include<set>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#define m(x) memset(x,0,sizof x);
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 1e5+10;
int n;
string a,b;
void f(int i,int j){
if(i>j)return;
int k;n++;
//在b数组中寻找root
for(k=i;k<=j;k++)if(a[n]==b[k])break;
//递归操作er
f(i,k-1);
f(k+1,j);
cout << b[k];
}
int main(){
while(cin >> a >> b){
n = -1;
f(0,a.size()-1);
cout << endl;
}
return 0;
}
类似的题目(就加个vector就完事了)
ZCMU-1132
总结
对二叉树的知识做了更深的总结