二叉树的遍历
已知一课二叉树的前序遍历和中序遍历,求它的后序遍历。
那么我们就需要了解前序遍历,中序遍历,后序遍历的遍历过程。
前序遍历:子节点—>左子树—>右子树
中序遍历:左子树—>子节点—>右子树
后序遍历:左子树—>右子树->子节点
举个栗子
c
/ \
/ \
B G
/ \ /
A D H
/ \
E F
这棵树的前序遍历为CBADEFGH;
中序遍历为ABEDFCHG;(将所有节点往下拖到一行,就可以得到中序遍历)别问我怎么知道的,问就是曦神永远滴神
后序遍历为AEFDBHGC;
那么问题来了
我们怎样通过前序遍历和中序遍历求后序遍历呢
那么我们得分析一下前序遍历的特点,首先前序遍历第一个肯定是根节点 。我们可以根据这个特点,找到根节点在中序遍历中的位置;
前序:CBADEFGH->>>CBADEFGH
中序:ABEDFCHG->>>>ABEDFCHG
那么ABEDF就是C的左子树,HG就是C的右子树
即
中序 c
/
/
ABEDF GH
前序
c
/
/
BADEF GH
然后再次对前序和中序的左子树和右子树重复以上操作,因此在代码中实现就可以用递归。
但是这需要对字符串进行切割。
C++中的string里有一个函数交substr
substr(i,k);
就是从字符串的下标i开始,切割的k个字符串。
例如
string a="ABCDEFG";
cout<<a.substr(0,4);
得到的结果就是ABCD
如果只含有一个参数i 即substr(i);
那么得到的就是从i到尾的字符串
例如
string a="ABCDEFG";
cout<<a.substr(1);
得到的就是BCDEFG
还有就是find函数
只要输入下标,就能传回该字母;
下面代码中会体现。
关门放代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 0x3f3f3f3f;
using namespace std;
string str1, str2;//str1表示中序字符串,str2表示前序字符串
void dfs(string pre, string mid)//搜索
{
if (pre.empty())return;//如果前序串为空
char pos = pre[0];//先储存前序的第一个字母,即根节点
int x = mid.find(pos);//在中序遍历找到根节点
string leftmid=mid.substr(0, x);//切割中序序列的左子树串
string rightmid = mid.substr(x + 1);//切割中序序列的右子树串
string leftpre = pre.substr(1, x);//切割前序序列左子树串
string rightpre = pre.substr(x+1);//切割前序序列右子树串
dfs(leftpre, leftmid);//递归,先搜左子树
dfs(rightpre, rightmid);//再搜右子树
cout << pos;//输出根节点
}
int main()
{
cin >> str1 >> str2;
dfs(str2, str1);
return 0;
}