[資料結構]二叉樹之二叉連結串列的類模板實現
阿新 • • 發佈:2019-01-10
該類模板實現了一個二叉樹的模板類,採用二叉連結串列實現。
定義二叉樹節點類,採用二叉連結串列實現。
///////////////////////// #include <iostream> #include <cstdlib> #include <stack> #include <deque> using namespace std; template<class T> struct BinTreeNode //二叉樹節點類的定義,使用二叉連結串列 { T data; BinTreeNode<T> *leftChild, *rightChild; BinTreeNode():leftChild(NULL),rightChild(NULL){} BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):data(x),leftChild(l),rightChild(r){} };
二叉樹的模板類實現如下:可進行相應的功能擴充套件。
介面部分:
template<class T> class BinaryTree//二叉樹的模板類 { public: BinaryTree():root(NULL){} BinaryTree(char x):root(NULL),RefValue(x){} BinaryTree(const BinaryTree<T>& rhs){root=copy(rhs.root);}//copy建構函式 BinaryTree<T>& operator=(const BinaryTree<T>& rhs);//copy 賦值運算子;析構+copy建構函式 ~BinaryTree(){destroy(root);}//解構函式 bool isEmpty()const{return root!=NULL?false:true;} BinTreeNode<T>* leftChild(BinTreeNode<T>* current)const{return current!=NULL?current->leftChild:NULL;} BinTreeNode<T>* rightChild(BinTreeNode<T>* current)const{return current!=NULL?current->rightChild:NULL;} BinTreeNode<T>* parent(BinTreeNode<T>* current)const{return (root==NULL || current==root)?NULL:parent(root,current);}//尋找其父節點 BinTreeNode<T>* getRoot()const{return root;} void inOrder(void (*visit)(BinTreeNode<T> *p)){inOrder(root,visit);}//中序遞迴遍歷 void preOrder(void (*visit)(BinTreeNode<T> *p)){preOrder(root,visit);}//前序遞迴 void postOrder(void (*visit)(BinTreeNode<T> *p)){postOrder(root,visit);}//後序遞迴 void levelOrder(void (*visit)(BinTreeNode<T> *p));//使用佇列的層次遍歷 int size()const {return size(root);}//使用後序遞迴遍歷求節點個數 int height()const {return height(root);}//使用後序遞迴遍歷求二叉樹的高度 protected: BinTreeNode<T> *root; char RefValue;//資料輸入停止標誌 void destroy(BinTreeNode<T>* subTree);//遞迴刪除二叉樹節點,後序遍歷刪除 BinTreeNode<T>* copy(const BinTreeNode<T> *orignode);//copy構造;前序 BinTreeNode<T>* parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const;//返回父節點 void traverse(BinTreeNode<T>* subTree,ostream& out)const;//按前序方式遍歷輸出每個節點的值 void createBinTree(istream& in,BinTreeNode<T>* & subTree);//採用廣義表表示的二叉樹建立方法 void inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//中序遍歷 void preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//前序遍歷 void postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//後序遍歷 int size(BinTreeNode<T> *subTree)const;//使用後序遞迴遍歷求節點個數 int height(BinTreeNode<T> *subTree)const;//使用後序遞迴遍歷求二叉樹的高度 friend ostream& operator<< <T>(ostream& out,const BinaryTree<T>& rhs);//add <T> 前序輸出二叉樹 friend istream& operator>> <T>(istream& in, BinaryTree<T>& rhs); //add <T> 採用廣義表表示方式建立二叉樹 };
相應成員函式的具體實現:
template<class T> void BinaryTree<T>::destroy(BinTreeNode<T>* subTree) { if(subTree!=NULL){ destroy(subTree->leftChild); destroy(subTree->rightChild); delete subTree; } } template<class T> BinTreeNode<T>* BinaryTree<T>::parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const { if(subTree==NULL) return NULL; if(subTree->leftChild==current || subTree->rightChild==current) return subTree; BinTreeNode<T>* p; if((p=parent(subTree->leftChild,current))!=NULL) return p else return parent(subTree->rightChild,current); } template<class T> void BinaryTree<T>::traverse(BinTreeNode<T>* subTree,ostream& out)const { if(subTree!=NULL){ out<<subTree->data<<" "; traverse(subTree->leftChild,cout); traverse(subTree->rightChild,out); } } template<class T> void BinaryTree<T>::createBinTree(istream& in,BinTreeNode<T>* & subTree) { stack<BinTreeNode<T>* > s; subTree=NULL; BinTreeNode<T> *p,*t; unsigned int k; T ch; in>>ch;//雖然是模板類,但是目前只支援字元型,不然會報錯 while(ch!=RefValue){ switch(ch){ case '(': s.push(p);k=1;break; case ')': s.pop();break; case ',': k=2;break; default: p=new BinTreeNode<T>(ch); if(subTree==NULL) subTree=p; else if(k==1) {t=s.top();t->leftChild=p;} else {t=s.top();t->rightChild=p;} } in>>ch; } } template<class T> ostream& operator<<(ostream& out,const BinaryTree<T>& rhs) { rhs.traverse(rhs.root,out); out<<endl; return out; } template<class T> istream& operator>>(istream& in, BinaryTree<T>& rhs) { rhs.createBinTree(in,rhs.root); return in; } template<class T> void BinaryTree<T>::inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p)) { if(subTree!=NULL){ inOrder(subTree->leftChild,visit); visit(subTree); inOrder(subTree->rightChild,visit); } } template<class T> void BinaryTree<T>::preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p)) { if(subTree!=NULL){ visit(subTree); inOrder(subTree->leftChild,visit); inOrder(subTree->rightChild,visit); } } template<class T> void BinaryTree<T>::postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p)) { if(subTree!=NULL){ inOrder(subTree->leftChild,visit); inOrder(subTree->rightChild,visit); visit(subTree); } } template<class T> int BinaryTree<T>::size(BinTreeNode<T> *subTree)const { if(subTree==NULL) return 0; else return 1+size(subTree->leftChild)+size(subTree->rightChild); } template<class T> int BinaryTree<T>::height(BinTreeNode<T> *subTree)const { if(subTree==NULL) return 0; else{ int i=height(subTree->leftChild); int j=height(subTree->rightChild); return (i>j)?i+1:j+1; } } template<class T> BinTreeNode<T>* BinaryTree<T>::copy(const BinTreeNode<T> *orignode) { if(orignode==NULL) return NULL; BinTreeNode<T> *temp=new BinTreeNode<T>; temp->data=orignode->data; temp->leftChild=copy(orignode->leftChild); temp->rightChild=copy(orignode->rightChild); return temp; } template<class T> BinaryTree<T>& BinaryTree<T>::operator=(const BinaryTree<T>& rhs) { this->destroy(this->root); this->root=copy(rhs.root); return *this; } template<class T> void BinaryTree<T>::levelOrder(void (*visit)(BinTreeNode<T> *p)) { deque<BinTreeNode<T>* > dq; BinTreeNode<T> *p=root; dq.push_back(p); while(!dq.empty()){ p=dq.front(); visit(p); dq.pop_front(); if(p->leftChild!=NULL) dq.push_back(p->leftChild); if(p->rightChild!=NULL) dq.push_back(p->rightChild); } }
測試函式:
int main(int argc, char* argv[])
{
BinaryTree<char> b('#');
cin>>b;
cout<<b<<endl;
//b.levelOrder(NULL);
//BinaryTree<char> a('#');
//cin>>a;
//cout<<a<<endl;
// b=a;
//cout<<b<<endl;
//BinaryTree<char> a=b;
//cout<<a<<endl;
//cout<<b.size()<<endl;
//cout<<b.isEmpty()<<endl;
//cout<<b.height()<<endl;
system("pause");
return 0;
}
測試結果:
a(b(c,d),e(f,g))#
a b c d e f g
請按任意鍵繼續. . .