【问题描述】
已知一个二叉树的前序遍历序列和中序遍历序列,求这棵树的后序遍历序列。
【输入形式】
一棵树的前序遍历序列和中序遍历序列,中间用换行符分开。输入序列中仅包含大小写字母,且没有重复的字母
【输出形式】
一个树的后序遍历序列
【样例输入】
ABCDEFGHI
BCAEDGHFI
【样例输出】
后序遍历:CBEHGIFDA
【思路】
首先找根节点的位置,因为有前序遍历,第一个节点就是根节点,然后在中序遍历中以找出的根节点为界划分左右子树,用递归构建出二叉树,再用后序遍历输出。
【题解代码】
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int MAX = 1000;
struct BiNode
{
char data;//数据域
BiNode* lchild, * rchild;//左右儿子指针
};
class BiTree {
private:
BiNode* root;
public:
//prestr是前序输入的字符串,instr是中序输入的字符串
BiTree(string prestr,string instr)
{
int lenpre = prestr.length();
int lenin = instr.length();
if (lenpre != lenin)root = NULL;//检查
else
{
root = creat(root, prestr, instr);//创建根节点
}
}
~BiTree() {
release(root);
}
BiNode* getRoot() { return root; }
BiNode* creat(BiNode* bt,string prestr,string instr); //构造函数调用
void release(BiNode* bt); //析构函数调用,释放树的存储空间
void preOrder(BiNode* bt);
void postOrder(BiNode* bt);
void inOrder(BiNode* bt);
};
//创建二叉树
BiNode* BiTree::creat(BiNode* bt, string prestr, string instr)//prestr是前序输入的字符串,instr是中序输入的字符串
{
if (prestr.length() == 0 || instr.length() == 0)//检查
return NULL;
else
{
int pos;//用来记录查找的根节点的位置下标
pos = instr.find(prestr[0]);//调用find函数在instr中查找根节点的下标并记录在pos中,
bt = new BiNode;
bt->data = prestr[0];//存储根节点
string prelstr = prestr.substr(1, pos);//prelstr用来保存根节点的左子树,用substr函数将左子树找到并保存在prelstr中。因为此时根节点在prestr中的第一个位置,所以截取的时候要从第二个位置开始,也就是从下标为1的位置开始
//pos也是要截取的字符串的长度,因为中序串的左侧都是左子树的结点,其节点个数就等于pos
string inlstr = instr.substr(0, pos);//同理,inlstr用来保存在instr中找到的左子树,此时的根节点并不在第一个位置,所以截取的时候要从头开始找,也就是从下标为0的位置开始
string prerstr = prestr.substr(pos + 1, prestr.length() - pos - 1);//再取右子树,因为这个是前序串嘛,前面已经把左子树和根节点都取到了,剩下的就都是右子树了,因此从根节点的后一位开始,到串结束为止都要截取,所以截取的长度是len-1-pos
string inrstr = instr.substr(pos + 1, instr.length() - pos - 1);//同理
bt->lchild = creat(bt->lchild, prelstr, inlstr);//已经取到左右子树了,那就递归创建呗
bt->rchild = creat(bt->rchild, prerstr, inrstr);
return bt;
}
return bt;
}
void BiTree::release(BiNode* bt)
{
if (bt != NULL)
{
release(bt->lchild);
release(bt->rchild);
delete bt;
}
}
void BiTree::preOrder(BiNode* bt)
{
if (bt == NULL)
{
return;
}
preOrder(bt->lchild);
preOrder(bt->rchild);
}
void BiTree::postOrder(BiNode* bt)
{
if (bt == NULL)
{
return;
}
postOrder(bt->lchild);
postOrder(bt->rchild);
cout << bt->data;
}
void BiTree::inOrder(BiNode* bt)
{
if (bt == NULL)
{
return;
}
inOrder(bt->lchild);
inOrder(bt->rchild);
}
int main()
{
string s1, s2;
cin >> s1 >> s2;
BiTree tree(s1,s2);
cout << "后序遍历:";
tree.postOrder(tree.getRoot());//后序输出二叉树
cout << endl;
return 0;
}