题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,且二叉树的节点个数 ≤8≤8)。
输入格式
共两行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
共一行一个字符串,表示一棵二叉树的先序。
解题思路
首先要知道一棵二叉树的后序遍历最后一个节点一定是整棵树的根节点, 而中序遍历的特点则是可以根据根节点把二叉树分成左右子树(即确定左右子树的数量和位置),那么这个题目就可以转化成不断找根节点的过程。大致分为这么几步:
step1:确定后序遍历最后一个节点的值(当前树的根节点), 并保存到先序遍历数组中即可。
step2:根据第一步中找到的值去确定其在中序遍历中的位置,以便把原中序遍历数组分成左子树和右子树
step3: 递归寻找左右子树的根节点还原先序遍历即可(如图可以分别遍历【B】和【DC】两棵子树(左子树和右子树))
step4:确定递归的边界条件:如上文所述,每一次递归遍历都是在中序遍历中寻找根节点,然后分成左右子树,那么对于每一层递归函数,如果中序遍历为空,则证明当前位置已经没有需要继续遍历的节点了(可以理解成nullptr),所以边界条件可以确定为中序遍历为空时函数返回进行回溯。
解题代码
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
string pre, in, post;
int n;
void dfs(string in, string post) {
if (in.size() == 0) return ;
char root = post[post.size() - 1];
pre.push_back(root);
int k = in.find(root);
dfs(in.substr(0, k), post.substr(0, k));
dfs(in.substr(k + 1), post.substr(k, in.size() - k - 1));
return ;
}
int main() {
cin >> in >> post;
n = in.size();
dfs(in, post);
cout << pre << endl;
return 0;
}
总结
此题考查的是对于二叉树三个遍历的还原操作,根据中序遍历与先序遍历和后序遍历任何一个都能还原出一个唯一的二叉树(当然也就可以还原出另外一个遍历),用深度优先搜索来解决的话就是不断去把大问题化成小问题的过程,本题求的是先序遍历,所以我们在递归寻找左右子树根节点之前需要先把根节点输出(或者存储),然后再递归遍历左右子树即可。