已知二叉树前序遍历和中序遍历,求其后续遍历。思路:前中两序还原二叉树 再进行后序遍历。

#include<iostream>
#include<string>
using namespace std;
struct node//定义一个二叉树的节点信息,此节点包含两个指针和一个字符
{
	node* lchid;//指向左孩子
	node* rchid;//指向右孩子
	char c;
}tree[55];
string f,m;//定义string类保存输入的两个序列
int cnt; //下标,用来标记新创建节点
node* creat()//创建新的节点返回的是指向这个新节点的指针
{
	
	tree[cnt].lchid = tree[cnt].rchid = NULL;
	return &tree[cnt++];
}
void postorder(node*T)//后序遍历,函数参数为指向根节点的指针
{
	if (T->lchid != NULL)//左孩子不空,则一直递归调用函数遍历到左孩子为空,然后一层一层回溯
		postorder(T->lchid);
	if (T->rchid != NULL)//右孩子不空,则一直递归调用函数遍历到右孩子为空,然后一层一层回溯
		postorder(T->rchid);
	cout << T->c;//打印节点字符信息
}
node* bf(int s1, int e1, int s2, int e2)//递归还原建造二叉树
{
	node* ret = creat();//一个新的节点指针指向新创建的节点;
	ret->c = f[s1];//节点的值为前序遍历的范围内的第一个节点的节点
	int rootx;
	for (int j = s2; j <=e2; j++)//找到这个节点在中序遍历中的位置
	{
		if (m[j] == f[s1])
		{
			rootx = j;
			break;
		}
	}
	if (rootx != s2)//如果这个位置不是在中序遍历范围的左端点,即意味着它有左孩子
	{
		ret->lchid = bf(s1 + 1, s1 + rootx - s2, s2, rootx - 1);//则,刚创建的ret的左孩子指针指向下一个递归建造的节点,当递归跳出当前函数时,
	}//由return ret这句函数返回这个节点信息,然后被ret->lchid指向,完成建立
	if (rootx != e2)//同理
	{
		ret->rchid = bf(s1 + rootx - s2+1, e1, rootx+1, e2);//同时注意这里的遍历范围,其实写s1+1,e1在有些没啥时间复杂度要求的地方可以,但是有要求就要按照代码中给出的范围写,不然会超时
	}
	return ret;
}
int main()
{
	while (cin >> f >> m)
	{
		cnt = 0;
		int len1 = f.length();
		int len2 = m.length();
		node* t = bf(0, len1-1, 0, len2-1);//一开始的遍历范围,前序:0-len-1,后:0-len-2;
		postorder(t);
		cout << endl;
	}
}