二叉树之二叉链表的类模板实现

该类模板实现了一个二叉树的模板类,采用二叉链表实现。

定义二叉树节点类,采用二叉链表实现。

  1. /  
  2. #include <iostream>  
  3. #include <cstdlib>  
  4. #include <stack>  
  5. #include <deque>  
  6. using namespace std;  
  7.   
  8.   
  9. template<class T>  
  10. struct BinTreeNode  //二叉树节点类的定义,使用二叉链表  
  11. {  
  12.     T data;  
  13.     BinTreeNode<T> *leftChild, *rightChild;  
  14.     BinTreeNode():leftChild(NULL),rightChild(NULL){}  
  15.     BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):data(x),leftChild(l),rightChild(r){}  
  16. };  

二叉树的模板类实现如下:可进行相应的功能扩展。

接口部分:

  1. template<class T>  
  2. class BinaryTree//二叉树的模板类  
  3. {  
  4. public:  
  5.     BinaryTree():root(NULL){}  
  6.     BinaryTree(char x):root(NULL),RefValue(x){}  
  7.     BinaryTree(const BinaryTree<T>& rhs){root=copy(rhs.root);}//copy构造函数  
  8.     BinaryTree<T>& operator=(const BinaryTree<T>& rhs);//copy 赋值运算符;析构+copy构造函数    
  9.     ~BinaryTree(){destroy(root);}//析构函数  
  10.   
  11.     bool isEmpty()const{return root!=NULL?false:true;}  
  12.     BinTreeNode<T>* leftChild(BinTreeNode<T>* current)const{return current!=NULL?current->leftChild:NULL;}  
  13.     BinTreeNode<T>* rightChild(BinTreeNode<T>* current)const{return current!=NULL?current->rightChild:NULL;}  
  14.     BinTreeNode<T>* parent(BinTreeNode<T>* current)const{return (root==NULL || current==root)?NULL:parent(root,current);}//寻找其父节点  
  15.     BinTreeNode<T>* getRoot()const{return root;}  
  16.   
  17.     void inOrder(void (*visit)(BinTreeNode<T> *p)){inOrder(root,visit);}//中序递归遍历  
  18.     void preOrder(void (*visit)(BinTreeNode<T> *p)){preOrder(root,visit);}//前序递归  
  19.     void postOrder(void (*visit)(BinTreeNode<T> *p)){postOrder(root,visit);}//后序递归  
  20.     void levelOrder(void (*visit)(BinTreeNode<T> *p));//使用队列的层次遍历  
  21.   
  22.     int size()const {return size(root);}//使用后序递归遍历求节点个数  
  23.     int height()const {return height(root);}//使用后序递归遍历求二叉树的高度  
  24.   
  25.   
  26.   
  27. protected:  
  28.     BinTreeNode<T> *root;  
  29.     char RefValue;//数据输入停止标志  
  30.   
  31.     void destroy(BinTreeNode<T>* subTree);//递归删除二叉树节点,后序遍历删除  
  32.     BinTreeNode<T>* copy(const BinTreeNode<T> *orignode);//copy构造;前序  
  33.   
  34.     BinTreeNode<T>* parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const;//返回父节点  
  35.     void traverse(BinTreeNode<T>* subTree,ostream& out)const;//按前序方式遍历输出每个节点的值  
  36.     void createBinTree(istream& in,BinTreeNode<T>* & subTree);//采用广义表表示的二叉树创建方法  
  37.   
  38.     void inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//中序遍历  
  39.     void preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//前序遍历  
  40.     void postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//后序遍历  
  41.   
  42.     int size(BinTreeNode<T> *subTree)const;//使用后序递归遍历求节点个数  
  43.     int height(BinTreeNode<T> *subTree)const;//使用后序递归遍历求二叉树的高度  
  44.       
  45.   
  46.     friend ostream& operator<< <T>(ostream& out,const BinaryTree<T>& rhs);//add <T> 前序输出二叉树  
  47.     friend istream& operator>> <T>(istream& in, BinaryTree<T>& rhs);      //add <T> 采用广义表表示方式创建二叉树  
  48.   
  49. };  

相应成员函数的具体实现:


  1. template<class T>  
  2. void BinaryTree<T>::destroy(BinTreeNode<T>* subTree)  
  3. {  
  4.     if(subTree!=NULL){  
  5.         destroy(subTree->leftChild);  
  6.         destroy(subTree->rightChild);  
  7.         delete subTree;  
  8.     }  
  9. }  
  10.   
  11. template<class T>  
  12. BinTreeNode<T>* BinaryTree<T>::parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const  
  13. {  
  14.     if(subTree==NULL) return NULL;  
  15.     if(subTree->leftChild==current || subTree->rightChild==current) return subTree;  
  16.       
  17.     BinTreeNode<T>* p;  
  18.     if((p=parent(subTree->leftChild,current))!=NULL)  
  19.         return p  
  20.     else   
  21.         return parent(subTree->rightChild,current);  
  22. }  
  23.   
  24. template<class T>  
  25. void BinaryTree<T>::traverse(BinTreeNode<T>* subTree,ostream& out)const  
  26. {  
  27.     if(subTree!=NULL){  
  28.         out<<subTree->data<<" ";  
  29.         traverse(subTree->leftChild,cout);  
  30.         traverse(subTree->rightChild,out);  
  31.     }  
  32. }  
  33.   
  34. template<class T>  
  35. void BinaryTree<T>::createBinTree(istream& in,BinTreeNode<T>* & subTree)  
  36. {  
  37.     stack<BinTreeNode<T>* > s;  
  38.     subTree=NULL;  
  39.     BinTreeNode<T> *p,*t;  
  40.     unsigned int k;  
  41.     T ch;  
  42.     in>>ch;//虽然是模板类,但是目前只支持字符型,不然会报错  
  43.     while(ch!=RefValue){  
  44.         switch(ch){  
  45.         case '(': s.push(p);k=1;break;  
  46.         case ')': s.pop();break;  
  47.         case ',': k=2;break;  
  48.         default:  
  49.             p=new BinTreeNode<T>(ch);  
  50.             if(subTree==NULL)  
  51.                 subTree=p;  
  52.             else if(k==1)  
  53.                 {t=s.top();t->leftChild=p;}  
  54.             else  
  55.                 {t=s.top();t->rightChild=p;}  
  56.         }  
  57.         in>>ch;  
  58.     }  
  59. }  
  60.   
  61. template<class T>  
  62. ostream& operator<<(ostream& out,const BinaryTree<T>& rhs)  
  63. {  
  64.     rhs.traverse(rhs.root,out);  
  65.     out<<endl;  
  66.     return out;  
  67. }  
  68.   
  69. template<class T>  
  70. istream& operator>>(istream& in, BinaryTree<T>& rhs)  
  71. {  
  72.     rhs.createBinTree(in,rhs.root);  
  73.     return in;  
  74. }  
  75.   
  76. template<class T>  
  77. void BinaryTree<T>::inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))  
  78. {  
  79.     if(subTree!=NULL){  
  80.         inOrder(subTree->leftChild,visit);  
  81.         visit(subTree);  
  82.         inOrder(subTree->rightChild,visit);  
  83.     }  
  84. }  
  85.   
  86. template<class T>  
  87. void BinaryTree<T>::preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))  
  88. {  
  89.     if(subTree!=NULL){  
  90.         visit(subTree);  
  91.         inOrder(subTree->leftChild,visit);  
  92.         inOrder(subTree->rightChild,visit);  
  93.     }  
  94. }  
  95.   
  96. template<class T>  
  97. void BinaryTree<T>::postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))  
  98. {  
  99.     if(subTree!=NULL){  
  100.         inOrder(subTree->leftChild,visit);  
  101.         inOrder(subTree->rightChild,visit);  
  102.         visit(subTree);  
  103.     }  
  104. }  
  105.   
  106. template<class T>  
  107. int BinaryTree<T>::size(BinTreeNode<T> *subTree)const  
  108. {  
  109.     if(subTree==NULL)  return 0;  
  110.     else  
  111.         return 1+size(subTree->leftChild)+size(subTree->rightChild);  
  112. }  
  113.   
  114. template<class T>  
  115. int BinaryTree<T>::height(BinTreeNode<T> *subTree)const  
  116. {  
  117.     if(subTree==NULL) return 0;  
  118.     else{  
  119.         int i=height(subTree->leftChild);  
  120.         int j=height(subTree->rightChild);  
  121.         return (i>j)?i+1:j+1;  
  122.     }  
  123. }  
  124.   
  125. template<class T>  
  126. BinTreeNode<T>* BinaryTree<T>::copy(const BinTreeNode<T> *orignode)  
  127. {  
  128.     if(orignode==NULL) return NULL;  
  129.     BinTreeNode<T> *temp=new BinTreeNode<T>;  
  130.     temp->data=orignode->data;  
  131.     temp->leftChild=copy(orignode->leftChild);  
  132.     temp->rightChild=copy(orignode->rightChild);  
  133.     return temp;  
  134. }  
  135.   
  136. template<class T>  
  137. BinaryTree<T>& BinaryTree<T>::operator=(const BinaryTree<T>& rhs)  
  138. {  
  139.     this->destroy(this->root);  
  140.     this->root=copy(rhs.root);  
  141.     return *this;  
  142. }  
  143.   
  144. template<class T>  
  145. void BinaryTree<T>::levelOrder(void (*visit)(BinTreeNode<T> *p))  
  146. {  
  147.     deque<BinTreeNode<T>* > dq;   
  148.     BinTreeNode<T> *p=root;  
  149.     dq.push_back(p);  
  150.     while(!dq.empty()){  
  151.         p=dq.front();  
  152.         visit(p);  
  153.         dq.pop_front();  
  154.   
  155.         if(p->leftChild!=NULL) dq.push_back(p->leftChild);  
  156.         if(p->rightChild!=NULL) dq.push_back(p->rightChild);  
  157.     }  
  158. }  


测试函数:

  1. int main(int argc, char* argv[])  
  2. {  
  3.   
  4.     BinaryTree<char> b('#');  
  5.     cin>>b;  
  6.     cout<<b<<endl;  
  7.   
  8.     //b.levelOrder(NULL);  
  9.   
  10.     //BinaryTree<char> a('#');  
  11.     //cin>>a;  
  12.     //cout<<a<<endl;  
  13.     // b=a;  
  14.     //cout<<b<<endl;  
  15.   
  16.     //BinaryTree<char> a=b;  
  17.     //cout<<a<<endl;  
  18.   
  19.     //cout<<b.size()<<endl;  
  20.     //cout<<b.isEmpty()<<endl;  
  21.     //cout<<b.height()<<endl;  
  22.   
  23.     system("pause");  
  24.     return 0;  
  25.   
  26. }  

测试结果:


a(b(c,d),e(f,g))#
a b c d e f g


请按任意键继续. . .




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值