#include <stdio.h>
#include<string.h>
const int N=20;
char s1[N], s2[N], ans[N];//s1[N],s2[N]分别为先序和中序遍历序列
void build(int n, char* s1, char* s2, char* s)
{
if(n <= 0) return;
int p = strchr(s2, s1[0]) - s2;//找到根结点的位置
build(p, s1+1, s2, s);//递归构造左子树的后序遍历
build(n-p-1, s1+p+1, s2+p+1, s+p);//递归构造右子树的后序遍历
s[n-1] = s1[0];//把根结点添加到最后
}
int main()
{
while(scanf("%s%s",s1, s2) == 2)
{
int n= strlen(s1);
build(n, s1,s2, ans);
ans[n] = '\0';
printf("%s\n",ans);
return 0;
}
}
将上述代码变形就可以得到:已知中序和后序遍历序列求前序遍历序列的代码:
#include <stdio.h>
#include<string.h>
const int N=20;
char s1[N], s2[N], ans[N];//s1[N],s2[N]分别为中序和后序遍历序列
void build(int n, char* s1, char* s2, char* s)
{
if(n <= 0) return;
int p = strchr(s1, s2[n-1]) - s1;//找根结点在s1中的位置
s[0] = s2[n-1];//把根结点添加到最前面
build(p, s1, s2, s+1);//递归构造左子树的先序遍历
build(n-p-1, s1+p+1, s2+p, s+p+1);//递归构造右子树的先序遍历
}
int main()
{
while(scanf("%s%s",s1, s2) == 2)
{
int n= strlen(s1);
build(n, s1,s2, ans);
ans[n] = '\0';
printf("%s\n",ans);
return 0;
}
}
不同之处仅在于build 的不同,仔细对比就可理解清楚。
以下给出另一种代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct BinaryTreeNode
{
char c;
BinaryTreeNode *lchild, *rchild;
BinaryTreeNode()
{
lchild = NULL, rchild = NULL;
}
};
struct BinaryTreeNode *root1,*root2;
char preorder[100], inorder[100], postorder[100];
void preSearch(BinaryTreeNode *root) //先序遍历树
{
if(root != NULL)
{
printf("%c", root->c);
preSearch(root->lchild);
preSearch(root->rchild);
}
return ;
}
void midSearch(BinaryTreeNode *root) //中序遍历树
{
if(root != NULL)
{
midSearch(root->lchild);
printf("%c", root->c);
midSearch(root->rchild);
}
return ;
}
void postSearch(BinaryTreeNode *root) //后序遍历树
{
if(root != NULL)
{
postSearch(root->lchild);
postSearch(root->rchild);
printf("%c", root->c);
}
return ;
}
void BuildTreeFromPreAndMid(BinaryTreeNode * &root, int ll, int lr, int len, int &now)//根据中序和先序求树
{
root = new BinaryTreeNode();
root->c = *(preorder + now);
int pos = (int)(strchr(inorder, *(preorder + now)) - inorder); //查找字符串中首次出现某个字符的位置
now++;
if(now >= len)
return ;
if(pos - 1 >= ll)
{
BinaryTreeNode *t = new BinaryTreeNode();
root->lchild = t;
BuildTreeFromPreAndMid(root->lchild, ll, pos - 1, len, now);
}
if(pos + 1 <= lr)
{
BinaryTreeNode *t = new BinaryTreeNode();
root->rchild = t;
BuildTreeFromPreAndMid(root->rchild, pos + 1, lr, len, now);
}
}
void BuildTreeFromPostAndMid(BinaryTreeNode * &root, int ll, int lr, int len, int &now)//根据中序和后序求树
{
root = new BinaryTreeNode();
root->c = *(postorder + now);
int pos = (int)(strchr(inorder, *(postorder + now)) - inorder);
now--;
if(now < 0)
return ;
if(pos + 1 <= lr)
{
BinaryTreeNode *t = new BinaryTreeNode();
root->rchild = t;
BuildTreeFromPostAndMid(root->rchild, pos + 1, lr, len, now);
}
if(pos - 1 >= ll)
{
BinaryTreeNode *t = new BinaryTreeNode();
root->lchild = t;
BuildTreeFromPostAndMid(root->lchild, ll, pos - 1, len, now);
}
}
//释放二叉树
inline void DeleteBinaryTree(BinaryTreeNode * &root)
{
if(root)
{
DeleteBinaryTree(root->lchild); //释放左子树
DeleteBinaryTree(root->rchild); //释放右子树
delete root; //释放根结点
}
}
int main(void)
{
gets(preorder);
gets(inorder);
//gets(postorder);
int now = 0;
BuildTreeFromPreAndMid(root1, 0, strlen(preorder) - 1, strlen(preorder), now);
//int now2 = strlen(postorder)-1;
//BuildTreeFromPostAndMid(root2, 0, strlen(postorder) - 1, strlen(postorder), now2);
postSearch(root1);
puts("");
DeleteBinaryTree(root1);
/*preSearch(root2);
puts("");
DeleteBinaryTree(root2);*/
return 0;
}