二叉树有三种遍历规则:
前序遍历:根-左子树-右子树 (对应树的先根遍历)
中序遍历:左子树-根-右子树 (对应树的后根遍历)
后序遍历:左子树-右子树-根
有上述规则可知:二叉树的结构可由 1.前序遍历 和中序遍历得到 2.中序遍历和 后序遍历得到
以 前序遍历 和中序遍历 ,求解后序遍历为例
设中序遍历结果 为S = S1,S2,S3,S4,.........Sn;
前序遍历结果 为X = X1,X2,X3,......Xn;
首先 可以到的整棵树的根节点为X1,那么就可以在S中查找根节点在中序遍历中的位置,假设为Sk,那么Sk左边的序列为整棵树的左子树,Sk右边的序列为整棵树的右子树,那么我们可以得到左右子树序列的长度(假设为L1,L2),那么左子树在前序遍历中的序列即为X2.....X(2+L1 -1),右子树序列为X(2 + L1)......Xn,那么我们用这种方法递归左右子树,就可以得到树的结构。递归的边界为,当树的序列长度为1 时停止递归 直接处理该结点。
#include <iostream>
#include <string>
using namespace std;
string prestr,instr;//先序,中序遍历结果
void solve(int prel,int prer,int inl,int inr)
{
int root,leftsize,rightsize;
for(root = inl;prestr[prel] != instr[root];root++);//找到中序遍历中的根
leftsize = root - inl;
rightsize = inr - root;
if(leftsize > 0)//如果存在左子树
{
solve(prel + 1,prel + leftsize,inl,inl + leftsize - 1);
}
if(rightsize > 0)//如果存在右子树
{
solve(prel + leftsize + 1,prer,root + 1,inr);
}
printf("%c",instr[root]);
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while(cin>>prestr>>instr)
{
solve(0,prestr.size() - 1,0,instr.size() - 1);
printf("\n");
}
}