二叉树的遍历分为递归和非递归。渐进的时间复杂度都是O(n),非递归算法由于没有函数递归调用的开销,有比较好的空间复杂度。
代码是根据邓俊辉老师的书来写的。
代码:
//traverse a binary tree in recursive or non recursive way
#include <iostream>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
using std::cin;
using std::cout;
using std::endl;
using std::cerr;
using std::stack;
using std::queue;
#define BinNodePosi(T) BinNode<T>*
#define IsRoot(x) (!(x).parent)
#define HasLChild(x) ((x).lc)
#define HasRChild(x) ((x).rc)
#define IsLChild(x) (!IsRoot(x)&&(&(x)==(x).parent->lc))
#define IsRChild(x) (!IsRoot(x)&&(&(x)==(x).parent->rc))
template <typename T>
void visit(T t)
{
cout<<t<<" "<<endl;
}
template <typename T> class BinNode
{
public:
T data;
BinNodePosi(T) parent;
BinNodePosi(T) lc;
BinNodePosi(T) rc;
int height;
BinNode():parent(NULL),lc(NULL),rc(NULL),height(0){}
BinNode(T e,BinNodePosi(T) p=NULL,BinNodePosi(T) lc=NULL,BinNodePosi(T) rc=NULL,int h=0):
data(e),parent(p),lc(lc),rc(rc),height(h){}
BinNodePosi(T) succ();
template <typename VST>
void travPost(VST &visit)
{
travPost_I(this,visit);
}
template <typename VST>
void travPre(VST &visit)
{
travPre_I(this,visit);
}
template <typename VST>
void travIn(VST &visit)
{
srand(time(NULL));
switch(rand()%2)
{
case 0:
cout<<"(use a stack)"<<endl;
travIn_I(this,visit);
break;
case 1:
cout<<"(not use a stack)"<<endl;
travIn_II(this,visit);
break;
default:
break;
}
}
template <typename VST>
void travPost_recursion(VST &visit)
{
if(this==nullptr)
return;
lc->travPost_recursion(visit);
rc->travPost_recursion(visit);
visit(this->data);
}
template <typename VST>
void travPre_recursion(VST &visit)
{
if(this==nullptr)
return;
visit(this->data);
lc->travPre_recursion(visit);
rc->travPre_recursion(visit);
}
template <typename VST>
void travIn_recursion(VST &visit)
{
if(this==nullptr)
return;
lc->travIn_recursion(visit);
visit(this->data);
rc->travIn_recursion(visit);
}
template <typename VST>
void travLevel(VST &visit,queue<BinNodePosi(T)> &Q)
{
visit(this->data);
if(lc)
Q.push(lc);
if(rc)
Q.push(rc);
}
BinNodePosi(T) insertAsLC(T const &);
BinNodePosi(T) insertAsRC(T const &);
};
template <typename T>
BinNodePosi(T) BinNode<T>::insertAsLC(T const &e)
{
lc=new BinNode(e,this);
return lc;
}
template <typename T>
BinNodePosi(T) BinNode<T>::insertAsRC(T const &e)
{
rc=new BinNode(e,this);
return rc;
}
template <typename T>
BinNodePosi(T) BinNode<T>::succ()
{
BinNodePosi(T) s=this;
if(rc)
{
s=rc;
while(HasLChild(*s))
s=s->lc;
}
else
{
while(IsRChild(*s))
s=s->parent;
s=s->parent;
}
return s;
}
template <typename T> class BinTree
{
public:
int _size;
BinNodePosi(T) _root;
public:
BinTree():_size(0),_root(NULL){}
int size() const {return _size;}
bool empty() const {return !_root;}
BinNodePosi(T) insertASRoot(T const &e);
BinNodePosi(T) insertASLC(BinNodePosi(T) x,T const &);
BinNodePosi(T) insertASRC(BinNodePosi(T) x,T const &);
template <typename VST>
void travPost_recursion(VST &visit)
{
if(_root)
_root->travPost_recursion(visit);
}
template <typename VST>
void travPre_recursion(VST &visit)
{
if(_root)
_root->travPre_recursion(visit);
}
template <typename VST>
void travIn_recursion(VST &visit)
{
if(_root)
_root->travIn_recursion(visit);
}
template <typename VST>
void travPost(VST &visit)
{
if(_root)
_root->travPost(visit);
}
template <typename VST>
void travPre(VST &visit)
{
if(_root)
_root->travPre(visit);
}
template <typename VST>
void travIn(VST &visit)
{
if(_root)
_root->travIn(visit);
}
template <typename VST>
void travLevel(VST &visit)
{
queue<BinNodePosi(T)> Q;
if(_root)
{
Q.push(_root);
while(!Q.empty())
{
BinNodePosi(T) cur=Q.front();
Q.pop();
cur->travLevel(visit,Q);
}
}
}
};
template <typename T>
BinNodePosi(T) BinTree<T>::insertASRoot(T const &e)
{
_root=new BinNode<T>(e);
_size=1;
return _root;
}
template <typename T>
BinNodePosi(T) BinTree<T>::insertASLC(BinNodePosi(T) x,T const &e)
{
x->insertAsLC(e);
_size++;
return x->lc;
}
template <typename T>
BinNodePosi(T) BinTree<T>::insertASRC(BinNodePosi(T) x,T const &e)
{
x->insertAsRC(e);
_size++;
return x->rc;
}
template <typename T>
static void gotoHLVFL(stack<BinNodePosi(T)> &S)
{
while(BinNodePosi(T) x=S.top())
{
if(HasLChild(*x))
{
if(HasRChild(*x))
S.push(x->rc);
S.push(x->lc);
}
else
S.push(x->rc);
}
S.pop();
}
template <typename T,typename VST>
void travPost_I(BinNodePosi(T) x,VST &visit)
{
stack<BinNodePosi(T)> S;
if(x)
S.push(x);
while(!S.empty())
{
if(S.top()!=x->parent)
gotoHLVFL(S);
x=S.top();
S.pop();
visit(x->data);
}
}
template <typename T,typename VST>
void visitAlongLeftPath(BinNodePosi(T) x,VST &visit,stack<BinNodePosi(T)> &S)
{
while(x)
{
visit(x->data);
if(HasRChild(*x))
S.push(x->rc);
x=x->lc;
}
}
template <typename T,typename VST>
void travPre_I(BinNodePosi(T) x,VST &visit)
{
stack<BinNodePosi(T)> S;
S.push(x);
while(!S.empty())
{
visitAlongLeftPath(x,visit,S);
x=S.top();
S.pop();
}
}
template <typename T>
void goAlongLeftPath(BinNodePosi(T) x,stack<BinNodePosi(T)> &S)
{
while(x)
{
S.push(x);
x=x->lc;
}
}
template <typename T,typename VST>
void travIn_I(BinNodePosi(T) x,VST &visit)
{
stack<BinNodePosi(T)> S;
goAlongLeftPath(x,S);
while(!S.empty())
{
x=S.top();
S.pop();
visit(x->data);
x=x->rc;
goAlongLeftPath(x,S);
}
}
template <typename T,typename VST>
void travIn_II(BinNodePosi(T) x,VST &visit)
{
bool backtrack=false;
while(true)
{
if(!backtrack&&HasLChild(*x))
x=x->lc;
else
{
visit(x->data);
if(HasRChild(*x))
{
x=x->rc;
backtrack=false;
}
else
{
if(!(x=x->succ()))
break;
backtrack=true;
}
}
}
}
int main()
{
BinTree<int> tree;
tree.insertASRoot(1);
BinNodePosi(int) l11=tree.insertASLC(tree._root,2);
BinNodePosi(int) l12=tree.insertASRC(tree._root,3);
BinNodePosi(int) l21=tree.insertASRC(l11,4);
BinNodePosi(int) l31=tree.insertASLC(l21,5);
BinNodePosi(int) l32=tree.insertASRC(l21,6);
BinNodePosi(int) l41=tree.insertASRC(l32,7);
cout<<"No recursion post order:"<<endl;
tree.travPost(visit<int>);
cout<<"recursion post order:"<<endl;
tree.travPost_recursion(visit<int>);
cout<<"No recursion pre order:"<<endl;
tree.travPre(visit<int>);
cout<<"recursion pre order:"<<endl;
tree.travPre_recursion(visit<int>);
cout<<"No recursion in order:"<<endl;
tree.travIn(visit<int>);
cout<<"recursion in order:"<<endl;
tree.travIn_recursion(visit<int>);
cout<<"level order:"<<endl;
tree.travLevel(visit<int>);
return 0;
}
运行结果: