template<class T>
struct BinTreeNode{
T elem;
BinTreeNode<T> *left;
BinTreeNode<T> *right;
BinTreeNode():left(NULL),right(NULL){}
BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):elem(x),left(l),right(r) {}
};
template<class T>
class BinTree{
public:
BinTree():root(NULL){}
BinTree(T value):retflag(value),root(NULL){}
BinTree(BinTree<T> &bt);
~BinTree(){_makeEmpty(root);}
bool IsEmpty(){return (root==NULL)?true:false;}
BinTreeNode<T>* GetParent(BinTreeNode<T> *btnode){
return (root==NULL || root==btnode)?NULL:_GetParent(root,btnode);
}
BinTreeNode<T>* GetLeft(BinTreeNode<T> *btnode){
return (btnode==NULL)?NULL:btnode->left;
}
BinTreeNode<T>* GetRight(BinTreeNode<T> *btnode){
return (btnode==NULL)?NULL:btnode->right;
}
int Height(){return _Height(root);}
int Size(){return _Size(root);}
BinTreeNode<T>* GetRoot()const{
return root;
}
void PreOrder(void (*visit)(BinTreeNode<T> *p)){
_PreOrder(root,visit);
}
void InOrder(void (*visit)(BinTreeNode<T> *p)){
_InOrder(root,visit);
}
void PostOrder(void (*visit)(BinTreeNode<T> *p)){
_PostOrder(root,visit);
}
void LevelOrder(void (*visit)(BinTreeNode<T> *p));
int Insert(const T &value);
BinTreeNode<T> *Find(T &value)const;
protected:
BinTreeNode<T> *root;
T retflag;
void _CreateBinTree(istream &in,BinTreeNode<T> *&subTree);
bool _Insert(BinTreeNode<T> *&subTree,const T &x);
void _makeEmpty(BinTreeNode<T> *&subTree);
bool _Find(BinTreeNode<T> *subTree,const T &x)const;
BinTreeNode<T>* _Copy(BinTreeNode<T> *subTree);
BinTreeNode<T>* _GetParent(BinTreeNode<T> *subTree,BinTreeNode<T> *btnode);
BinTreeNode<T>* _Find(BinTreeNode<T> *subTree,const T &x)const;
void _Traverse(BinTreeNode<T> *subTree,ostream &out);
void _PreOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> *subTree);
void _InOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> *subTree);
void _PostOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> *subTree);
friend ostream& operator<< (ostream &out,BinTree<T> &btree);
friend istream& operator>>(istream &in,BinTree<T> &btree);
int _Height(BinTreeNode<T> *btnode);
int _Size(BinTreeNode<T> *btnode);
};
void BinTree<T>::_makeEmpty(BinTreeNode<T> *subTree){
if(subTree!=NULL){
_makeEmpty(subTree->left);
_makeEmpty(subTree->right);
delete subTree;
}
/* if(subTree==NULL)
return NULL;
_makeEmpty(subTree->left);
_makeEmpty(subTree->right);
delete subTree;
*/
}
BinTreeNode<T>* BinTree<T>::_GetParent(BinTreeNode<T> *subTree,BinTreeNode<T> *btnode){
if(subTree==NULL)
return NULL;
if(subTree->left==btnode || subTree->right==btnode)
return subTree;
BinTreeNode<T> *p;
//search in left,if result has been taken,return
if((p=_GetParent(subTree->left,btnode))!=NULL)
return p;
//search in right
else
return (p=_GetParent(subTree->right,btnode));
}
template<class T>
void BinTree<T>::_Traverse(BinTreeNode<T> *subTree,ostream &out){
if(subTree==NULL}
return;
out<<"subTree->"<<subTree->elem<<" ";
_Traverse(subTree->left);
_Traverse(subTree->right);
out<<endl;
}
template<class T>
istream& BinTree<T>::operator>>(istream &in,BinTree<T> &btree){
_CreateBinTree(in,btree.root);
return in;
}
template<class T>
ostream& BinTree<T>::operator<<(ostream &out,BinTree<T> &btree){
_Traverse(btree.root,out);
return out;
}
template <class T>
void _CreateBinTree(istream &in,BinTreeNode<char> *&bt){
stack<BinTreeNode<char> *> st;
bt=NULL;
BinTreeNode<char> *p, *t;
int LorR;
//LorR=1,put elem in left;
//LorR=2,put elem in right;
char ch;
in>>ch;
while(ch!=retflag){
switch(ch){
case '(':LorR=1;break;
case ')':t=st.top();st.pop();break;
case ',':LorR=2;break;
default:
p=new BinTreeNode<char>(ch);
if(bt=NULL)
bt=p;
else if(LorR==1){
t=st.top();
t->left=p;
}
else{
t=st.top();
t->right=p;
}
st.push(p);
}
in>>ch;
}
}
template<class T>
void _PreOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> *subTree){
if(subTree!=NULL){
visit(subTree);
_InOrder(visit,subTree->left);
_InOrder(visit,subTree->right);
}
}
template<class T>
void _InOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> &subTree){
if(subTree!=NULL){
_InOrder(visit,subTree->left);
visit(subTree);
_InOrder(visit,subTree->right);
}
}
template<class T>
void _PostOrder(void (*visit)(BinTreeNode<T> *p),BinTreeNode<T> &subTree){
if(subTree!=NULL){
_PostOrder(visit,subTree->left);
_PostOrder(visit,subTree->right);
visit(subTree);
}
}
//postOrder
template<class T>
int _Height(BinTreeNode<T> *btnode){
if(btnode==NULL)
return 0;
else
int Max= max(_Height(btnode->left),_Height(btnode->right));
return Max+1;
}
template<class T>
int _Size(BinTreeNode<T> *btnode){
if(btnode==NULL)
return 0;
else
return _Size(btnode->left)+_Size(btnode->right);
}
//preOrder
template<class T>
BinTree(BinTree<T> &bt){
_Copy(bt.root);
}
template<class T>
BinTreeNode<T>* _Copy(BinTreeNode<T> *subTree){
if(subTree==NULL)
return NULL;
BinTreeNode<T> *bt;
bt=root;
bt=new BinTreeNode<T>(subTree->elem,NULL,NULL);
bt->left=_Copy(subTree->left);
bt->right=_Copy(subTree->right);
return bt;
}
template<class T>
bool operator==(const BinTree<T> &t1,const BinTree<T> &t2){
return IsEqual(t1.root,t2.root);
}
bool IsEqual(BinTreeNode<T> *t1,BinTreeNode<T> *t2){
BinTreeNode<T> *bt1=t1,*bt2=t2;
if(bt1==NULL && bt2==NULL)
return true;
if(bt1!=NULL&&bt2!=NULL&&bt1->elem==bt2->elem&&IsEqual(bt1->left,bt2->left)==true&&IsEqual(bt1->right,bt2->right)==true)
return true;
else
return false;
}
template<class T>
void _CreateBinTree(istream &in,BinTreeNode<T> *&subTree){
T data;
in>>data;
if(!in.eof()){
if(data==retflag){
subTree= NULL;
}
else{
subTree=new BinTreeNode<T>(data,NULL,NULL);
assert(subTree!=NULL);
_CreateBinTree(in,subTree->left);
_CreateBinTree(in,subTree->right);
}
}
}
- 利用栈来遍历二叉树
-使用栈时要注意栈是否为空栈
//preOrder and inOrder by stack
template<class T>
void BinTree<T>::preOrder(void(*visit)(BinTreeNode<T> *p)){
stack<BinTreeNode<T> *> st;
st.push(root);
while(st.empty()==false){
p=st.top();
st.pop();
if(p->right!=NULL)
st.push(p->right);
if(p->left!=NULL)
st.push(p->left);
}
}
template<class T>
void BinTree<T>::inOrder(void(*visit)(BinTreeNode<T> *p)){
stack<BinTreeNode<T> *> st;
BinTreeNode<T> *p;
do{
while(p!=NULL){
st.push(p);
p=p->left;
}
//no left child
if(s.empty()==false){
p=st.top();
st.pop();
visit(p);
p=p->right;
/* if(p!=NULL)
st.push(p); */
}
}while(st.empty()==false || p!=NULL);
}
- 层序遍历
template<class T>
void BinTree<T>::levelOrder(void(*visit)(BinTreeNode<T> *p)){
queue<BinTreeNode<T> *> q;
BinTreeNode<T> *p=root;
q.push(p);
while(p!=NULL||q.empty()==false){
p=q.front();
if(p->left!=NULL){
q.push(p->left);
}
if(p->right!=NULL){
q.push(p->right);
}
q.pop();
visit();
}
}
/*
C++队列Queue类成员函数如下:
back()返回最后一个元素
empty()如果队列空则返回真
front()返回第一个元素
pop()删除第一个元素
push()在末尾加入一个元素
size()返回队列中元素的个数
*/
后序遍历
template<class T>
struct tagNode{
BinTreeNode<T> *node;
enum tag{L,R};
tagNode(BinTreeNode<T> *t=NULL):p(NULL),tag(L);
};
template<class T>
void BinTree<T>::postOrder(void(*visit)(BinTreeNode<T> *p)){
stack<tagNode<T> > st;
tagNode<T> w;
BinTreeNode<T> *p=root;
do{
while(p!=NULL){
w=tagNode<T>(p);
st.push(w);
p=p->left;
}
int flag=1;
//continue loopp by &1,break loop by &0
while(st.empty()==false&&t){
w=st.top();
st.pop();
p=w.node;
switch(w.tag){
case L:
w.tag=R;
st.push(w);
flag=0;
p=p->right;
break;
case R:
visit(p);
break;
}
}
}while(st.empty()==false);
}