这个主要是先序中序建立二叉树吧,先序里的是树或子树的根节点,所以要在中序中找到这个根节点,左边就是左子树了,右边是右子数啦(详细注释有),建立好树就直接后序遍历啦;
后序遍历写了递归和非递归的,非递归难一些,其他的一样
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
typedef char TElemType;
//二叉树的二叉链表存储表示
typedef struct BiTNode {
TElemType data; //结点数据域
struct BiTNode *lchild, *rchild; //左右孩子指针
} BiTNode, *BiTree;
//根据先序序列pre[pre_low..pre_low+len-1]和中序序列in[in_low..in_low+len-1]建树t
void BuildTree(BiTree& t, char pre[], int pre_low, char in[], int in_low, int len)
{
/****在此下面完成代码************/
if(len<=0)t=NULL;//长度为0,t就没有数据啦
else{
t=new BiTNode;
t->data=pre[0];//先序的第一个是这一段的根
char root=pre[0];//存根
int i;
for(i=0;i<len;i++){//从中序中找到这个根的位置i
if(in[i]==root)break;
}
BuildTree(t->lchild,pre+1,0,in,0,i);//i位置左边的数值是这一段的左子树
BuildTree(t->rchild,pre+i+1,0,in+i+1,0,len-(i+1));//右边是右子树
}
/*********************************/
}
// 后序遍历的递归算法
void PostOrderTraverse(BiTree t)
{
/****在此下面完成代码************/
if(!t)return;
else{
PostOrderTraverse(t->lchild);
PostOrderTraverse(t->rchild);
cout<<t->data;
}
/*********************************/
}
void DestroyBitree(BiTree& t)
{
/****在此下面完成代码************/
if(!t)return ;
else{
if(t->lchild)DestroyBitree(t->lchild);
if(t->rchild)DestroyBitree(t->rchild);
delete t;
t=NULL;
}
/*********************************/
}
int main()
{
char pre[30], in[30];
BiTree t = NULL;
while(cin >> pre) {
cin >> in;
BuildTree(t, pre, 0, in, 0, strlen(in));
PostOrderTraverse(t);
DestroyBitree(t);
cout << endl;
}
}
后序遍历非递归 ,用了栈,主要头文件的stack
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
typedef char TElemType;
//二叉树的二叉链表存储表示
typedef struct BiTNode {
TElemType data; //结点数据域
struct BiTNode *lchild, *rchild; //左右孩子指针
} BiTNode, *BiTree;
stack<BiTree>a;
//根据先序序列pre[pre_low..pre_low+len-1]和中序序列in[in_low..in_low+len-1]建树t
void BuildTree(BiTree& t, char pre[], int pre_low, char in[], int in_low, int len)
{
/****在此下面完成代码************/
if(len<=0)t=NULL;//长度为0,t就没有数据啦
else{
t=new BiTNode;
t->data=pre[0];//先序的第一个是这一段的根
char root=pre[0];//存根
int i;
for(i=0;i<len;i++){//从中序中找到这个根的位置i
if(in[i]==root)break;
}
BuildTree(t->lchild,pre+1,0,in,0,i);//i位置左边的数值是这一段的左子树
BuildTree(t->rchild,pre+i+1,0,in+i+1,0,len-(i+1));//右边是右子树
}
/*********************************/
}
// 后序遍历的递归算法
void PostOrderTraverse(BiTree t)
{
/****在此下面完成代码************/
if(!t)return ;//t不存在
else{
BiTree r=NULL;//记录每次输出的数据域
while(t||!a.empty()){//t为空,且栈里没数的时候退出
if(t){
a.push(t);//树和子树的根节点先不输出
t=t->lchild;//往左边一直走
}
else{
t=a.top();//t是NULL
if(t->rchild&&t->rchild!=r){//右字数有数据且未曾访问过
t=t->rchild;//指向右子树
a.push(t);//入栈
t=t->lchild;//往左边找
}
else{
cout<<t->data;//输出
a.pop();//出栈
r=t;//t访问过了,存下来
t=NULL;//因为访问队列中下一个值
}
}
}
}
/*********************************/
}
void DestroyBitree(BiTree& t)
{
/****在此下面完成代码************/
if(!t)return ;
else{
if(t->lchild)DestroyBitree(t->lchild);
if(t->rchild)DestroyBitree(t->rchild);
delete t;
t=NULL;
}
/*********************************/
}
int main()
{
char pre[30], in[30];
BiTree t = NULL;
while(cin >> pre) {
cin >> in;
BuildTree(t, pre, 0, in, 0, strlen(in));
PostOrderTraverse(t);
DestroyBitree(t);
cout << endl;
}
}