二叉树的非递归调用需要借助栈,为了方便我们直接使用c++中自带的栈。
#include<stack>
下面我们来分别介绍前序遍历,中序遍历,后序遍历的算法。
参考教科书,前序遍历的伪代码如下:
1.栈的初始化
2.循环直到bt为空且栈为空;
2.1 当bt不为空时循环:
2.1.1 输出bt->data;
2.1.2 将指针bt保存到栈中;
2.1.3 继续遍历bt的左子树;
2.2 如果栈不为空,则
2.2.1 将栈顶元素弹出至bt;
2.2.2 准备遍历bt的右子树;
代码如下:
template<class T>
void BiTree<T>::PreOrder(BiNode<T>*bt)
{
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
cout<<bt->data<<endl;
s.push(bt);
bt=bt->lchild;
}
if(!s.empty())
{
bt=s.top();
s.pop();
bt=bt->rchild;
}
}
}
中序遍历伪代码:
1.栈的初始化
2.循环直到bt为空且栈为空;
2.1 当bt不为空时循环:
2.1.1 将指针bt保存到栈中;
2.1.2 继续遍历bt的左子树;
2.2 如果栈不为空,则
2.2.1 将栈顶元素弹出至bt;
2.2.2 输出bt->data;
2.2.3 准备遍历bt的右子树;
代码如下:
template<class T>
void BiTree<T>::InOrder(BiNode<T>*bt)
{
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
s.push(bt);
bt=bt->lchild;
}
if(!s.empty())
{
bt=s.top();
s.pop();
cout<<bt->data<<endl;
bt=bt->rchild;
}
}
}
后序遍历伪代码:
1.栈的初始化;
2.循环直到bt为空且栈为空
2.1 当bt非空循环
2.1.1 将bt连通标志flag=1入栈;
2.1.2 继续遍历bt的左子树;
2.2 当栈为空且栈顶元素的标志为2时,出栈并输出栈顶结点;
2.3 若栈非空,将栈顶元素的标志改为2,准备遍历栈顶结点的左子树;
下面为后序遍历非递归代码:
template<class T>
void BiTree<T>::PostOrder(BiNode<T>*bt)
{
BiNode<T>*pre=NULL;
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
s.push(bt);
bt=bt->lchild;
}
bt=s.top();
if(bt->rchild==NULL||bt->rchild==pre)
{
cout<<bt->data<<endl;
pre=bt;
s.pop();
bt=NULL;
}
else
{
bt=bt->rchild;
}
}
}
以下为非递归遍历的完整代码:
#include<iostream>
#include<stack>
#include<string>
using namespace std;
template<class T>
struct BiNode
{
T data;
BiNode<T>*lchild,*rchild; //左孩子和右孩子指针
};
template<class T>
class BiTree
{
private:
BiNode<T>*root; //指向根节点的头指针
BiNode<T>*Creat(BiNode<T>*bt);//构造函数的调用
void Relief(BiNode<T>*bt); //析构函数的调用
void PreOrder(BiNode<T>*bt); //前序遍历函数的调用
void InOrder(BiNode<T>*bt); //中序遍历函数的调用
void PostOrder(BiNode<T>*bt); //后续遍历函数的调用
public:
BiTree(){root=Creat(root);}
~BiTree(){Relief(root);}
void PreOrder(){PreOrder(root);}
void InOrder(){InOrder(root);}
void PostOrder(){PostOrder(root);}
};
template<class T>
BiNode<T>*BiTree<T>::Creat(BiNode<T>*bt)
{
T ch;
bt=new BiNode<T>;
cin>>ch;
if(ch=='#')
{
return NULL;
}
else
{
bt->data=ch;
bt->lchild=Creat(bt->lchild);
bt->rchild=Creat(bt->rchild);
}
return bt;
}
template<class T>
void BiTree<T>::Relief(BiNode<T>*bt)
{
if(bt!=NULL)
{
Relief(bt->lchild);
Relief(bt->rchild);
delete bt;
}
}
template<class T>
void BiTree<T>::PreOrder(BiNode<T>*bt)
{
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
cout<<bt->data<<endl;
s.push(bt);
bt=bt->lchild;
}
if(!s.empty())
{
bt=s.top();
s.pop();
bt=bt->rchild;
}
}
}
template<class T>
void BiTree<T>::InOrder(BiNode<T>*bt)
{
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
s.push(bt);
bt=bt->lchild;
}
if(!s.empty())
{
bt=s.top();
s.pop();
cout<<bt->data<<endl;
bt=bt->rchild;
}
}
}
template<class T>
void BiTree<T>::PostOrder(BiNode<T>*bt)
{
BiNode<T>*pre=NULL;
stack<BiNode<T>*> s;
while(bt!=NULL||!s.empty())
{
while(bt!=NULL)
{
s.push(bt);
bt=bt->lchild;
}
bt=s.top();
if(bt->rchild==NULL||bt->rchild==pre)
{
cout<<bt->data<<endl;
pre=bt;
s.pop();
bt=NULL;
}
else
{
bt=bt->rchild;
}
}
}
int main()
{
BiTree<char> bi;
cout<<"Pre:"<<endl;
bi.PreOrder();
cout<<endl;
cout<<endl;
cout<<"In:"<<endl;
bi.InOrder();
cout<<endl;
cout<<endl;
cout<<"Post"<<endl;
bi.PostOrder();
cout<<endl;
cout<<endl;
return 0;
}
运行截图: