C++二叉树实现
#include<iostream> #include<stack> #include<queue> using namespace std; template <class T> class BinTreeNode { private: T data; BinTreeNode<T> *left; BinTreeNode<T> *right; public: BinTreeNode(const T& dt=NULL,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):data(dt),left(l),right(r) {}; BinTreeNode<T> * GetLeft(void)const { return left; } BinTreeNode<T> * GetRight(void)const { return right; } T GetData()const { return data; } void SetLeft(BinTreeNode<T>* l) { left=l; ///此处赋值,非构造函数 } void SetRight(BinTreeNode<T>* r) { right=r; } void SetData(const T& dt) { data=dt; } }; template <class T> class BinTree { private: BinTreeNode<T> *root; T stop;///构造二叉树时的输入结束符 int index=-1;///使用数组构造二叉树时用于遍历数组元素 public: BinTree(BinTreeNode<T>* rt=NULL):root(rt) {}; virtual ~BinTree() { Del(root); } ///二叉树的创建,通过io输入创建与通过数组创建,均为先序 BinTreeNode<T>* Create(); BinTreeNode<T>* CreateFromArr(T*a); ///节点删除 void DelSubtree(BinTreeNode<T>* t);///从树中删除结点t及其左右子树 void Del(BinTreeNode<T>* t);///删除结点t及其左右子树 ///递归前中后序遍历 void PreOrder(BinTreeNode<T>* t)const; void InOrder(BinTreeNode<T>* t)const; void PostOrder(BinTreeNode<T>* t)const; ///非递归前中后续遍历 void NorecPreOrder()const; void NorecInOrder()const; void NorecPostOrder()const; ///其他操作 BinTreeNode<T>* GetRoot() const { return root; } void SetRoot(BinTreeNode<T>* t) { root=t; } T GetStop()const { return stop; } void SetStop(const T& s) { stop=s; } bool IsEmpty()const { return root==NULL; } }; ///从数组创建一个二叉树 template <class T> BinTreeNode<T>* BinTree<T>::CreateFromArr(T* a) { BinTreeNode<T>* root = NULL; //cout<<index<<">>>"<<a[index]<<endl; index++; if (a[index] != stop) { root = new BinTreeNode<T>(a[index]); root->SetLeft(CreateFromArr(a)); root->SetRight(CreateFromArr(a)); } return root; } ///由io流创建一个二叉树 template <class T> BinTreeNode<T>* BinTree<T>::Create() { BinTreeNode<T>* t,*t1,*t2; T item; cin>>item; ///递归出口 if(item==stop) { t=NULL; return t; } ///先续构造二叉树 else { t=new BinTreeNode<T>(item,NULL,NULL); t1=Create(); t->SetLeft(t1); t2=Create(); t->SetRight(t2); return t; } } ///递归遍历 template <class T> void BinTree<T>::Del(BinTreeNode<T> *t) { if(t!=NULL) { Del(t->GetLeft()); Del(t->GetRight()); delete t; } } template <class T> void BinTree<T>::PreOrder(BinTreeNode<T>* t)const { if(t!=NULL) { cout<<t->GetData()<<"->"; PreOrder(t->GetLeft()); PreOrder(t->GetRight()); } } template <class T> void BinTree<T>::PostOrder(BinTreeNode<T>* t)const { if(t!=NULL) { PostOrder(t->GetLeft()); PostOrder(t->GetRight()); cout<<t->GetData()<<"->"; } } template <class T> void BinTree<T>::InOrder(BinTreeNode<T>* t)const { if(t!=NULL) { InOrder(t->GetLeft()); cout<<t->GetData()<<"->"; InOrder(t->GetRight()); } } ///非递归遍历 template <class T> void BinTree<T>::NorecPreOrder()const { BinTreeNode<T> *p=root; stack<BinTreeNode<T>*> s; while(p||!s.empty()) { if(p) { cout<<p->GetData()<<"->"; s.push(p); p=p->GetLeft(); } else { p=s.top(); s.pop(); p=p->GetRight(); } } return; } template <class T> void BinTree<T>::NorecInOrder() const { stack<BinTreeNode<T>*> s; BinTreeNode<T> *p=root; while(p||!s.empty()) { if(p) { s.push(p); p=p->GetLeft(); } else { p=s.top(); cout<<p->GetData()<<"->"; s.pop(); p=p->GetRight(); } } return; } ///后序遍历:这是三种遍历方法中最为复杂的一种, ///因为它的根节点是最后访问的,在我们出栈遇到该节点时, ///我们并不知道此时它的右子树是否被访问过, ///所以我们需要额外借助一个节点变量用来判断右子树的访问真值。 template <class T> void BinTree<T>::NorecPostOrder() const { BinTreeNode<T> *p=root,*temp=NULL; stack<BinTreeNode<T> *>s; while(p||!s.empty())///只有p为空切栈为空时,退出循环 { if(p) { s.push(p); p=p->GetLeft(); } else { p=s.top(); ///p的右子树非空且p的右子树不为temp(标志节点) ///此时p的右子树还未遍历过 if(p->GetRight()&&p->GetRight()!=temp) { p=p->GetRight(); s.push(p); p=p->GetLeft(); } ///当右子树已经遍历过时或右子树为空,此时应该进行节点的输出 else { s.pop(); cout<<p->GetData()<<"->"; temp=p; p=NULL; } } } return; } int main() { char arr[]= {'A','B','D','#','G','#','#','E','#','#','C','F','#','#','#'}; /* A Pre :ABDGECF / \ In :DGBEAFC B C Post:GDEBFCA / \ / \ D E F # / \ / \ / \ # G # # # # / \ # # */ BinTree<char> *tree=new BinTree<char>; tree->SetStop('#'); cout<<"CreatTheTree"<<endl; ///由io流创建 ///BinTreeNode<char> *rt=tree->Create(); ///由数组创建 BinTreeNode<char> *rt=tree->CreateFromArr(arr); tree->SetRoot(rt); cout<<endl; cout<<"PreOrder>>>"; tree->PreOrder(tree->GetRoot()); cout<<endl; cout<<"InOrder>>>"; tree->InOrder(tree->GetRoot()); cout<<endl; cout<<"PostOrder>>>"; tree->PostOrder(tree->GetRoot()); cout<<endl; cout<<"NorecPreOrder>>>"; tree->NorecPreOrder(); cout<<endl; cout<<"NorecInOrder>>>"; tree->NorecInOrder(); cout<<endl; cout<<"NorecPostOrder>>>"; tree->NorecPostOrder(); cout<<endl; }