#include<iostream>
#include<stack>
#include<cstdlib>
using namespace std;
typedef struct BiTree
{
char ch;
struct BiTree *lchild,*rchild;
}BiTree,*pBiTree;
void BuildBiTree(pBiTree &p)//先序遍历创建二叉树
{
char c;
cin>>c;
if(c=='#')
p=NULL;
else
{
p=new BiTree;
p->ch=c;
BuildBiTree(p->lchild);
BuildBiTree(p->rchild);
}
}
void visit(pBiTree &p)
{
if(p==NULL)
{
cout<<"error"<<endl;
exit(0);
}
cout<<p->ch;
}
void PreOrder(pBiTree p)//先序遍历访问二叉树
{
stack<pBiTree> s;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
visit(p);//先访问根结点
p=p->lchild;//再访问左结点
}//直到最左边没有结点,准备访问右结点
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;//最后访问右结点
}
}
}
void InOrder(pBiTree p)//中序遍历访问二叉树
{
stack<pBiTree> s;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}//先把左结点都压入栈
if(!s.empty())
{
p=s.top();
visit(p);//从左结点开始访问
s.pop();
p=p->rchild;
}
}
}
void PostOrder(pBiTree p)//后序遍历访问二叉树
{
stack<pBiTree> s;
pBiTree t=p;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}//先把左节点都存进栈
pBiTree pre=NULL;
while(!s.empty())
{
p=s.top();
if(p->rchild==NULL||p->rchild==pre)//p的左子节点为空,或者已经访问过了,只需判断右子节点是否为空或者访问过
{
visit(p);
pre=p;//表明P结点已访问过
s.pop();
}
else
{
p=p->rchild;//右结点不为空并且没有访问过
break;//进入上一个循环,把右结点的左结点都存进栈
}
}
if(pre==t)//整个二叉树访问过后又会进入上一个循环,一直重复,所以如果根结点访问过后就退出
break;
}
}
int main()
{
pBiTree p=NULL;
BuildBiTree(p);
PreOrder(p);
cout<<endl;
InOrder(p);
cout<<endl;
PostOrder(p);
cout<<endl;
return 0;
}
/*
*ABD#H##E##CFI###G##
*/