题目描述
二叉树的前序、中序、后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树; 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树; 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
输入描述:
两个字符串,其长度n均小于等于26。 第一行为前序遍历,第二行为中序遍历。 二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。
输出描述:
输入样例可能有多组,对于每组测试样例, 输出一行,为后序遍历的字符串。
输入例子:
ABC BAC FDXEAG XDEFAG
输出例子:
BCAXEDGAF
#include <iostream> #include <cstring> using namespace std; typedef struct BinaryTree { char data; BinaryTree* lchild; BinaryTree* rchild; }BinaryTree; void RebuildTree(BinaryTree* &Tree,char* pre,char* in,int len) { Tree = (BinaryTree*)malloc(sizeof(BinaryTree)); if(Tree!=NULL) { if(len<=0) {//递归截止条件 Tree = NULL; return ; } int index = 0; while(index<len&&*(pre)!=*(in+index)) {//寻找当前的root结点(包含子树) index++; } Tree->data = *(pre); RebuildTree(Tree->lchild,pre+1,in,index);//去掉root结点 RebuildTree(Tree->rchild,pre+1+index,in+1+index,len-(index+1));//去掉左边和根节点 } return ; } void PostOrderTravese(BinaryTree* Tree) {//后序遍历输出 if(Tree==NULL) return; PostOrderTravese(Tree->lchild); PostOrderTravese(Tree->rchild); printf("%c",Tree->data); } int main() { char pre[101]; char in[101]; while(scanf("%s %s",pre,in)!=EOF) { BinaryTree* tree; int length = strlen(pre); RebuildTree(tree,pre,in,length); PostOrderTravese(tree); cout<<endl; } return 0; }
参考代码:struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; TreeNode* rebuildBinaryTree(const vector<int>& pre,int prestart, int preend, const vector<int>& vin, int vinstart, int vinend) { if(prestart > preend ) return NULL; TreeNode* phead = new TreeNode(pre[prestart]); int cout = vinstart; while(pre[prestart] != vin[cout]) cout++; phead->left = rebuildBinaryTree(pre, prestart+1, prestart+cout-vinstart, vin, vinstart, cout-1); //左边重构树 phead->right = rebuildBinaryTree(pre, prestart+cout-vinstart+1, preend, vin, cout+1, vinend);//右边重构树 return phead; } TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { return rebuildBinaryTree(pre, 0, pre.size()-1, vin, 0, vin.size()-1); }