#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
typedef char ElemType;
class BiTNode
{
friend class BiTree;
private:
ElemType data;
BiTNode *lchild,*rchild; //左右孩子指针
};
class BiTree:public BiTNode
{
public:
void InputBiTNode(); //输入构成数的结点元素,‘#’表示空串
void Pre_CreateBiTree(BiTNode *&T); //先序构造二叉树
void visit(ElemType e); //visit函数用于输出结点元素
void PreOrderTraverse(BiTNode *T); //先序遍历二叉树T(递归方式)
void InOrderTraverse(BiTNode *T); //中序遍历二叉树T(递归方式)
void PostOrderTraverse(BiTNode *T); //后序遍历二叉树T(递归方式)
void Iterator_PreOrderTraverse(BiTNode *T); //先序遍历二叉树T(非递归方式)
void Iterator_InOrderTraverse(BiTNode *T); //中序遍历二叉树T(非方递归式)
void Iterator_PostOrderTraverse(BiTNode *T);//后序遍历二叉树T(非递归方式)
void Iterator_PreOrderTraverse2(BiTNode *T); //先序遍历二叉树T(非递归方式2)
void Iterator_InOrderTraverse2(BiTNode *T); //中序遍历二叉树T(非方递归式2)
void Iterator_PostOrderTraverse2(BiTNode *T);//后序遍历二叉树T(非递归方式2)
private:
vector<ElemType> elem;
};
void BiTree::InputBiTNode()
{
ElemType ch;
cout<<"!!!注意:(1)'#'表示空结点;(2)请在输入的字符串末尾加0,作为输入结束的标志。"<<endl;
while(cin>>ch&&ch!='0')
{
elem.push_back(ch); //在容器中加入结点元素
}//while
}//InputBiBode
void BiTree::Pre_CreateBiTree(BiTNode *&T)
{
vector<ElemType>::iterator it=elem.begin(); //迭代器it指向elem的开头
if(it!=elem.end())
{
if(*it=='#')//字符为空格,表示结点不存在
{
T=NULL;
elem.erase(it); //删除迭代器it指向的elem中的元素,作用是依次删除elem的第一个元素
}//if
else
{
if(!(T=new BiTNode))
exit(-1);
T->data=*it; //生成根结点
elem.erase(it); //删除迭代器it指向的elem中的元素,作用是依次删除elem的第一个元素
Pre_CreateBiTree(T->lchild); //构造左子树
Pre_CreateBiTree(T->rchild); //构造右子树
}//else
}//if
else //此时elem为空,使此时T=NULL;,即结束最初的T的结点的赋值
T=NULL;
}//Pre_CreateBiTree
void BiTree::PreOrderTraverse(BiTNode *T)
{
if(T) //二叉树存在
{
visit(T->data); //访问根结点
PreOrderTraverse(T->lchild); //先序遍历左子树
PreOrderTraverse(T->rchild); //先序遍历右子树
}//if
}//PreOrderTraverse
void BiTree::InOrderTraverse(BiTNode *T)
{
if(T)
{
InOrderTraverse(T->lchild); //中序遍历左子树
visit(T->data); //访问根结点
InOrderTraverse(T->rchild); //中序遍历右子树
}//if
}//InOrderTraverse
void BiTree::PostOrderTraverse(BiTNode *T)
{
if(T)
{
PostOrderTraverse(T->lchild); //后序遍历左子树
PostOrderTraverse(T->rchild); //后序遍历右子树
visit(T->data); //访问根结点
}//if
}//PostOrderTraverse
void BiTree::Iterator_PreOrderTraverse(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q;
S.push(T); //根指针入栈
while(!S.empty())
{
while((q=S.top())&&q) //先访问结点,再将结点的左子树入栈,栈顶为空指针结束
{
visit(q->data);
S.push(q->lchild);
}//while
S.pop(); //空指针出栈
if(!S.empty()) //由于结点元素已被访问,因此此处只需删除结点,将结点的右结点入栈
{
q=S.top();S.pop(); //访问结点时将其从栈中删除
S.push(q->rchild);
}//if
}//while
}//Iterator_PreOrderTraverse
void BiTree::Iterator_InOrderTraverse(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q;
S.push(T); //根指针入栈
while(!S.empty())
{
while((q=S.top())&&q) //向左走到尽头
{
S.push(q->lchild);
}//while
S.pop(); //空指针出栈
if(!S.empty()) //访问结点,将结点的右结点入栈
{
q=S.top();S.pop(); //访问结点时将其从栈中删除
visit(q->data);
S.push(q->rchild); //将右结点入栈
}//if
}//while
}//Iterator_InOrderTraverse
void BiTree::Iterator_PostOrderTraverse(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q,*point=T;
S.push(T); //根指针入栈
while(!S.empty())
{
while((q=S.top())&&q) //向左走到尽头
{
S.push(q->lchild);
}//while
S.pop(); //空指针出栈
if(!S.empty())
{
q=S.top();
S.push(q->rchild); //右结点入栈
if(S.top()==NULL) //入栈的右结点为空
{
S.pop(); //空指针出栈
point=S.top();S.pop(); //访问根结点并出栈
visit(point->data);
while((!S.empty())&&(S.top()->rchild==point)) //栈顶结点的右结点是刚被访问的结点
{
point=S.top();S.pop(); //由于该结点的右结点已经被访问,说明完成了左右子树的遍历
visit(point->data); //该结点作为子树的根结点则被出栈访问
}//while
if(!S.empty())
{
q=S.top(); //此时栈顶结点的右结点还未入栈
S.push(q->rchild); //右结点入栈
}//if
}//if
}//if
}//while
}//Iterator_PostOrderTraverse
void BiTree::Iterator_PreOrderTraverse2(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q=T;
while(q||(!S.empty()))
{
if(q)
{
visit(q->data); //访问根结点
S.push(q);
q=q->lchild; //遍历左子树
}//if
else
{
q=S.top();S.pop(); //采用先序遍历,结点入栈时已被访问,因此出栈时无需访问
q=q->rchild;
}//else
}//while
}//Iterator_PreOrderTraverse2
void BiTree::Iterator_InOrderTraverse2(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q=T;
while(q||(!S.empty()))
{
if(q) //结点存在
{
S.push(q); //根指针进栈,遍历左子树,
q=q->lchild;
}//if
else //根指针退栈,访问根结点
{
q=S.top();S.pop();
visit(q->data);
q=q->rchild; //遍历右子树
}//else
}//while
}//Iterator_InOrderTraverse2
void BiTree::Iterator_PostOrderTraverse2(BiTNode *T)
{
stack<BiTNode*> S; //用来存储树结点的
BiTNode *q=T,*point=T;
while(q||(!S.empty()))
{
if(q)
{
S.push(q); //根指针进栈,遍历左子树
q=q->lchild;
}//if
else
{
q=S.top();
q=q->rchild; //遍历右子树
if(!q) //将要入栈的右子树为空
{
point=S.top();S.pop(); //在遍历完左右子树后访问根结点
visit(point->data);
while((!S.empty())&&(S.top()->rchild==point)) //栈顶结点的右结点是刚被访问的结点
{
point=S.top();S.pop(); //由于该结点的右结点已经被访问,说明完成了左右子树的遍历
visit(point->data); //该结点作为子树的根结点则被出栈访问
}//while
if(!S.empty())
{
q=S.top(); //此时栈顶结点的右结点还未入栈
q=q->rchild; //右结点入栈
}//if
}//if
}//else
}//while
}//Iterator_PostOrderTraverse2
void BiTree::visit(ElemType e)
{
cout<<e;
}//visit
void main()
{
BiTree BT;
BiTNode *T;
BT.InputBiTNode();
BT.Pre_CreateBiTree(T);
cout<<"\n"<<"先序遍历(递归)二叉树T:"<<endl;
BT.PreOrderTraverse(T);cout<<endl;
cout<<"先序遍历(非递归)二叉树T:"<<endl;
BT.Iterator_PreOrderTraverse(T);cout<<endl;
cout<<"先序遍历(非递归2)二叉树T:"<<endl;
BT.Iterator_PreOrderTraverse2(T);cout<<endl;
cout<<"\n"<<"中序遍历(递归)二叉树T:"<<endl;
BT.InOrderTraverse(T);cout<<endl;
cout<<"中序遍历(非递归)二叉树T:"<<endl;
BT.Iterator_InOrderTraverse(T);cout<<endl;
cout<<"中序遍历(非递归2)二叉树T:"<<endl;
BT.Iterator_InOrderTraverse2(T);cout<<endl;
cout<<"\n"<<"后序遍历(递归)二叉树T:"<<endl;
BT.PostOrderTraverse(T);cout<<endl;
cout<<"后序遍历(非递归)二叉树T:"<<endl;
BT.Iterator_PostOrderTraverse(T);cout<<endl;
cout<<"后序遍历(非递归2)二叉树T:"<<endl;
BT.Iterator_PostOrderTraverse2(T);cout<<endl;
}//main
以下图所示二叉树为例,对中序(非递归)和后序(非递归2)算法栈的入栈和出栈情况进行简单说明: