二叉树完整实现C++
来源:互联网 发布:中文域名注册查询 编辑:程序博客网 时间:2024/06/05 18:43
总结网上一位大牛写的代码,看看人家,就写一个二叉树,就把C++继承多态的作用发挥出来,看咱只能简单定义一个class, 差距大啊~自己还是小白~
BinaryTree.h
#ifndef BINARY_TREE#define BINARY_TREE#include <iostream>#include <string>#include <stdexcept>#include <stack>using namespace std;enum ChildID{LEFTCHILD = 0, RIGHTCHILD};//子节点类型,左节点or右节点;template<class T> class BinaryTree;template<class T> class BTreeNode{friend class BinaryTree<T>;public:BTreeNode(): pParent(0), pLChild(0), pRChild(0){}BTreeNode(T elem, BTreeNode<T>* parent=0, BTreeNode* lchild=0, BTreeNode* rchild=0):pParent(parent),pLChild(lchild),pRChild(rchild),data(elem) {}T GetData() const; //获取节点数据;T& GetDataRef(); //不应当提供这样的接口,这里仅仅让iterator能够自由访问存储的数据;BTreeNode* GetParent() const;//获取节点的父节点BTreeNode* GetLChild() const;//获取节点的左孩子节点BTreeNode* GetRChild() const;//获取节点的右孩子节点void SetData(const T& elem );//修改节点的数据;/*下面是更改节点的指针域结构的function,是否真的需要,还得仔细考量做为树的节点,一般不允许直接访问节点中的指针数据,如果这些数据在树被建立完成以后修改,会破坏树的结构;*/void SetParent( BTreeNode<T>* parent, ChildID CHID ); //设置当前节点的父节点,并指定当前节点作为子节点的类型;void SetLeft( BTreeNode<T>* left); //设置当前节点的左子节点;void SetRight( BTreeNode<T>* right); //设置当前节点的右子节点;private:BTreeNode<T>* pParent;BTreeNode<T>* pLChild;BTreeNode<T>* pRChild;T data;};//declare BTreeNode end//*********************************************************// BTreeNode Implementation//*********************************************************template<class T> T BTreeNode<T>::GetData() const{ return data;}template<class T>T& BTreeNode<T>::GetDataRef(){ return data;}template<class T>T BTreeNode<T>::GetParent() const{ return pParent;}template<class T>T BTreeNode<T>::GetRChild() const{ return pRChild;}template<class T>T BTreeNode<T>::GetLChild() const{ return pLChild;}template<class T>T BTreeNode<T>::SetData(const T& elem){ data = elem;}template<class T>void BTreeNode<T>::SetParent(BTreeNode<T>* parent, ChildID CHID ){if(!parent) return;if(CHID==LEFTCHILD) //当前节点作为parent的左子节点;{pParent = parent;parent->pLChild = this;}else if (CHID==RIGHTCHILD){pParent = parent;parent->rLChild = this;}}template<class T>void BTreeNode<T>::SetLeft(BTreeNode<T>* left){ pLChild=left; }template<class T>void BTreeNode<T>::SetRight(BTreeNode<T>* right){ pRChild=right; }// BTreeNode Implementation over//*********************************************************//*********************************************************template<class T> class BinaryTree{public:BinaryTree() : root(NULL){}BinaryTree( T value) : RefValue(value), root(NULL) {}BinaryTree( const BinaryTree<T>& tree); //copy ConstruBcture privatedBinaryTree<T>& operator=(const BinaryTree<T>& tree); //operator= privatedvirtual ~BinaryTree();virtual int IsEmpty(){return root==NULL;}/* * 下面三个函数的可用性,返回值类型的正确性值得考量 * 这样做不仅会破坏树的结构,而且很容易引起内存泄漏 * 在一般的树中最好不要提供这三个接口 ; */virtual BTreeNode<T>* Parent( BTreeNode<T>* current ); //返回所给结点父结点;virtual BTreeNode<T>* LeftChild( BTreeNode<T>* current); //返回节点的左孩子;virtual BTreeNode<Ty>* RightChild( BTreeNode<T>* current); //返回节点的右孩子;virtual bool Insert( const T& item); //插入元素;virtual bool Find( const T& item) const; //搜索元素;const BTreeNode<T>* GetRoot() const; //取树根;//遍历操作void PreOrder() const; //前序;void InOrder() const; //中序;void PostOrder() const; //后序;//二叉树特性操作函数int Size() const;int Size( const BTreeNode<T>* troot) const;int Height() const;int Height( const BTreeNode<T>* troot) const;bool operator==( const BinaryTree<T>& tree) const;//下面的接口是以不同的方式来构建二叉树BinaryTree<T>& AutoCreateTree(const std::string& expstr); //自动判断格式并建立BinaryTree<T>& PreOrderCreateTree(const std::string& expstr); //先序建立BinaryTree<T>& PostOrderCreateTree(const std::string& expstr); //后续建立protected:BTreeNode< T>* Parent( BTreeNode<T>* start, BTreeNode<T>* current );int Insert( BTreeNode<T>* current, const T& item);void Travers( BTreeNode<T>* current, std::ostream& out ) const;void Find( BTreeNode<T>* current, const T& item ) const;void destroy( BTreeNode<T>* current); //遍历递归void InOrder( BTreeNode<T>* current) const;void PreOrder( BTreeNode<T>* current ) const;void PostOrder( BTreeNode<T>* current) const;//二叉树特性递归操作函数BTreeNode<T>* Copy( BTreeNode<T>* troot, BTreeNode<T>* parent);bool equal( BTreeNode<T>* troot1, BTreeNode<T>* troot2) const;//建树用的递归函数BTreeNode<T>* PreOrderCreateNode(const char* &expstr, BTreeNode<T>* parent); //先序递归建立二叉树BTreeNode<T>* PostOrderCreateNode(const char* &expstr, BTreeNode<T>* parent); //后续递归建立二叉树//声明一组用于二叉树的迭代器iteratorprivate:class iterator; //迭代器基类friend class iterator;public:class PreOrder_iterator; //前序迭代器class InOrder_iterator; //中序迭代器class PostOrder_iterator; //后序迭代器class LevelOrder_iterator; //层序迭代器friend class PreOrder_iterator;friend class InOrder_iterator;friend class PostOrder_iterator;friend class LevelOrder_iterator;private:BTreeNode< T >* root; //树的根指针 T RefValue; //数据输入终结标志};//END BinaryTree/********************************** * implament of template BinaryTree * **********************************/template <class T> BinaryTree<T>::BinaryTree( const BinaryTree<T>& tree) //copy Constructor{root = Copy(tree.root, NULL);}template <class T> BinaryTree<T>& BinaryTree<T>::operator=( const BinaryTree<T>& tree) //operator= constructor{destroy(root);root = Copy(tree.root, NULL);return *this;}template <class T> BinaryTree<T>::~BinaryTree(){destroy(root); //遍历删除二叉树}template <class T> bool BinaryTree<T>::Insert( const T& item){return true;}template <class T>bool BinaryTree<T>::Find( const T& item) const{return true;} template <class T>BTreeNode<T>* BinaryTree<T>::Parent( BTreeNode<T>* current){if( root == NULL || root == current ){return NULL;}else{return current->pParent;}/* * 由于节点保留了parent的地址,所以可以直接取得父节点的地址 * 但是节点中如果没有parent的数据,就必须调用递归查询来寻找父节点的地址 * 代码片断如下,它调用了Parent( BTreeNode<T> *start, BTreeNode<T>* current) return (root == NULL || root == current) ? NULL : Parent( root, current); */ }template <class T>BTreeNode<T>* BinaryTree<T>::LeftChild( BTreeNode<T>* current){return current != NULL ? current->pLChild : NULL;}template <class T>BTreeNode<T>* BinaryTree<T>::RightChild( BTreeNode<T>* current){return current != NULL ? current->pRChild : NULL; }template <class T>BTreeNode<T>* BinaryTree<T>::Parent( BTreeNode<T> *start, BTreeNode<T>* current){//从结点start开始,搜索节点current的父结点,//如果找到其父节点,则函数将其返回,否则返回 NULLif( !start ) return NULL;if( start->pLChild == current || start->pRChild == current) return start;BTreeNode<T> *pNode;if((pNode = Parent( start->pLChild, current)) != NULL) {return pNode; } else {return Parent( start->pRChild, current); } }template <class T> const BTreeNode<T>* BinaryTree<T>::GetRoot() const{return root;}template <class T>void BinaryTree<T>::Travers( BTreeNode<T>* current, std::ostream& out) const {//前序输出根为current的二叉数if( current ) {out << current->data;Travers( current->pLChild , out );Travers( current->pRChild, out );}else{out<<"#";}}//中序遍历操作template <class T>void BinaryTree<T>::InOrder() const {std::cout << "InOrder Traval Tree:/n";InOrder( root );std::cout << std::endl; }template <class T>void BinaryTree<T>::InOrder( BTreeNode<T>* current) const{//递归私有函数,中序遍历二叉树if(current != NULL) {InOrder(current->pLChild);std::cout << current->data; InOrder(current->pRChild); } else {std::cout << "#";}}//前序遍历操作template <class T>void BinaryTree<T>::PreOrder() const {std::cout << "PreOrder Travel Tree:/n";PreOrder (root);std::cout << std::endl; }template <class T>void BinaryTree<T>::PreOrder( BTreeNode<T>* current) const{if(current != NULL) {std::cout << current->data;PreOrder(current->pLChild);PreOrder(current->pRChild);}else{std::cout <<"#";}}//后序遍历操作template <class T>void BinaryTree<T>::PostOrder() const {//后序遍历std::cout << "PostOrder Travel Tree:/n";PostOrder(root);std::cout << std::endl; }template <class T>void BinaryTree<T>::PostOrder( BTreeNode<T>* current) const{//后序递归操作if( current != NULL ) {PostOrder(current->pLChild);PostOrder(current->pRChild);std::cout << current->data;}else{std::cout << "#";}}//计算二叉树的结点数template <class T>int BinaryTree<T>::Size() const { return Size(root);} template <class T>int BinaryTree<T>::Size( const BTreeNode<T>* troot) const { if(troot == NULL) return 0; //空树,返回0 else return 1 + Size(troot->pLChild) + Size(troot->pRChild); } //计算二叉树的高度template <class T>int BinaryTree<T>::Height() const{ return Height(root);} template <class T>int BinaryTree<T>::Height( const BTreeNode<T>* troot) const { if ( troot == NULL ) return -1; else return 1 + MAX( Height( troot->pLChild ) , Height( troot->pRChild) );} //递归拷贝的私有函数;template <class T>BTreeNode<T>* BinaryTree<T>::Copy( BTreeNode<T>* troot, BTreeNode<T>* parent) { if (NULL == troot) return NULL; BTreeNode<T>* pNode = new BTreeNode<T>; pNode->data = troot->data; //拷贝数据 pNode->pParent = parent; pNode->pLChild = Copy( troot->pLChild, pNode ); //新建左子树 pNode->pRChild = Copy( troot->pRChild, pNode ); //新建右子树 return pNode; //返回树根结点} //判断二叉树内容是否相等template <class T>bool BinaryTree<T>::operator==( const BinaryTree<T>& tree) const { return equal( root, tree.root );} //判断二叉树相等的递归操作template <class T>bool BinaryTree<T>::equal( BTreeNode<T>* troot1, BTreeNode<T>* troot2) const { if( NULL == troot1 && NULL == troot2 ) return true; if( (NULL == troot1 && NULL != troot2) || (NULL != troot1 && NULL == troot2) || (troot1->data != troot2->data) ) { return false; } else { return equal( troot1->pLChild, troot2->pLChild) && equal( troot1->pRChild, troot2->pRChild); } return true;} template <class T> void BinaryTree<T>::destroy( BTreeNode<T>* current) { if( current ) { destroy( current->pLChild ); //递归删除左结点 destroy( current->pRChild); //除右节点 delete current; current = NULL; //空置指针 }} //define of Max functiontemplate <class _T>_T MAX(const _T& a, const _T& b){ return (a>=b) ? a : b; } //*********************************************************//1:先序方式建立二叉树 template <class T>BinaryTree<T>& BinaryTree<T>::PreOrderCreateTree(const std::string& expstr){ using namespace std; const char* exp = expstr.c_str(); if(*exp != '#') //以#开头表示字符串不是先序表达式 { destroy(root); root = PreOrderCreateNode(exp, NULL); } else { cout << "Your string expression error, I can't Create B-Tree :)/n"; } return *this; } template <class T>BTreeNode<T>*BinaryTree<T>::PreOrderCreateNode(const char* &expstr, BTreeNode<T>* parent){ if( *expstr == '#' || *expstr == '/0') return NULL; BTreeNode<T>* pnewNode = new BTreeNode<T>(*expstr, parent); assert(pnewNode); pnewNode->pLChild = PreOrderCreateNode(++expstr, pnewNode); pnewNode->pRChild = PreOrderCreateNode(++expstr, pnewNode); return pnewNode;} //********************************************************* //********************************************************* //3:后续方式建立二叉树template <class T>BinaryTree<T>& BinaryTree<T>::PostOrderCreateTree(const std::string& expstr){ using namespace std; const char* exp = expstr.c_str(); if( expstr.size() < 3) { destroy(root); return *this; } if(*exp == '#' && *(exp+1) == '#' && *(exp+2) == '#' ) //以 ##'X' 开头表示字符串是后续序表达式 'X'表示元素 { destroy(root); exp += expstr.size()-1; root = PostOrderCreateNode(exp, NULL); //反向遍历生成 } else { cout << "Your string expression error, I can't Create B-Tree :)/n"; } return *this; } template <class T>BTreeNode<T>*BinaryTree<T>::PostOrderCreateNode(const char* &expstr, BTreeNode<T>* parent){ if( *expstr == '#') return NULL; BTreeNode<T>* pnewNode = new BTreeNode<T>(*expstr, parent); assert(pnewNode); pnewNode->pRChild = PostOrderCreateNode(--expstr, pnewNode); pnewNode->pLChild = PostOrderCreateNode(--expstr, pnewNode); return pnewNode;} //********************************************************//********************************************************//三种迭代器的实现 //iterator 是私有的基类迭代器,这里没有实现常量树的迭代器 const_iterator//这样做确保了用户不可能访问到这个迭代器template <class T>class BinaryTree<T>::iterator {public: iterator():m_btree(NULL), pCurrent(NULL){} virtual ~iterator() {} virtual iterator& operator= (const iterator& iter) { pCurrent = iter.pCurrent; return *this; } virtual iterator& GotoFirst() = 0; //游标索引到第一个节点 virtual bool IsEnd() = 0; //游标是否已经索引到末尾 virtual iterator& operator++() = 0; // 游标自增 //virtual iterator operator++(int) = 0; virtual const T& current() const; virtual T& operator*(); virtual T* operator->();protected: BinaryTree<T>* m_btree; BTreeNode<T>* pCurrent; }; template <class T>const T& BinaryTree<T>::iterator::current() const { if(pCurrent != NULL) { return pCurrent->GetDataRef(); } else { throw std::out_of_range("iterator error/n"); }} template <class T>T& BinaryTree<T>::iterator::operator*(){ if(pCurrent != NULL) { return pCurrent->GetDataRef(); } else { throw std::out_of_range("iterator error/n"); } } template <class T>T* BinaryTree<T>::iterator::operator->(){ if(pCurrent != NULL) { return &(pCurrent->GetDataRef()); } else { throw std::out_of_range("iterator error/n"); } } //*********************************************************//这里采用两种方式来遍历树//1:采用简单计数栈的非递归遍历(要求结点中有父节点数据域)//2:采用栈的非递归遍历(在最后注释部分)//********************************************************* //前序遍历迭代器(无栈) template <class T>class BinaryTree<T>::PreOrder_iterator : public iterator { using iterator::pCurrent; using iterator::m_btree;public: PreOrder_iterator() {} PreOrder_iterator(const BinaryTree<T>& tree ) { m_btree = const_cast< BinaryTree<T>* >(&tree); GotoFirst();//索引至第一个结点; } PreOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; pCurrent = iter.pCurrent; } PreOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); pCurrent = NULL; } else { pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot()); //强制转换为非常量指针 stk.Push(1); //记录当前树的根节点访问次数 } return *this; } bool IsEnd() { return pCurrent == NULL; } PreOrder_iterator& operator++() ; // 游标自增; //PreOrder_iterator operator++(int); private: stack<int> stk; //保存访问节点的遍历次数的栈;}; template <class T> BinaryTree<T>::PreOrder_iterator& BinaryTree<T>::PreOrder_iterator::operator++() //前序后继节点;{ if( stk.IsEmpty() ) //确保迭代器是有效的; { return *this; } //访问左子节点 if( pCurrent->GetLeft() == NULL) //左节点无效; { stk.Pop(); stk.Push(2); //pCurrent 第二次访问; //查询右节点; if( pCurrent->GetRight() == NULL) //右节点也无效; { //回溯搜索有效的节点 while( !stk.IsEmpty() && stk.Pop()==2 ) { pCurrent = pCurrent->GetParent(); } stk.Push(1); //节点的右子节点不可访问,继续回溯,搜索到跟节点,停止搜索; while(pCurrent != NULL && pCurrent->GetRight() == NULL ) { pCurrent = pCurrent->GetParent(); stk.Pop(); } //如果已经搜索出根节点,抛出异常; if(pCurrent == NULL) { //throw std::out_of_range("BinaryTree iterator over/n"); } else { stk.Pop(); stk.Push(2); //pCurrent访问计数2; pCurrent = pCurrent->GetRight(); stk.Push(1); } } else //右节点有效 { pCurrent = pCurrent->GetRight(); stk.Push(1); } } else //左节点有效 { pCurrent = pCurrent->GetLeft(); stk.Push(1); } return *this;} //中序遍历迭代器//InOrder_iterator template <class T>class BinaryTree<T>::InOrder_iterator : public iterator { using iterator::pCurrent; using iterator::m_btree;public: InOrder_iterator() {} InOrder_iterator(const BinaryTree<T>& tree ) { m_btree = const_cast< BinaryTree<T>* >(&tree); GotoFirst(); //索引至第一个结点 } InOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; pCurrent = iter.pCurrent; } InOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); pCurrent = NULL; } else { pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot()); if( pCurrent != NULL ) { stk.Push(1); //节点计数进1 while( pCurrent->GetLeft() != NULL ) { pCurrent = pCurrent->GetLeft(); stk.Push(1); } } } return *this; } bool IsEnd() { return pCurrent == NULL; } InOrder_iterator& operator++() // 游标自增1 { if(IsEnd()) { return *this; } if( pCurrent->GetRight() == NULL) { stk.Pop(); stk.Push(2); while( !stk.IsEmpty() && stk.Pop() == 2) { pCurrent = pCurrent->GetParent(); } stk.Push(2); return *this; } else { //右节点有效 stk.Pop(); stk.Push(2); pCurrent = pCurrent->GetRight(); stk.Push(1); while( pCurrent->GetLeft() != NULL) { pCurrent = pCurrent->GetLeft(); stk.Push(1); } } return *this; } //InOrder_iterator operator++(int); private: ChainStack<int> stk; //保存访问节点的遍历次数的栈 }; //**********************************************************//后序遍历迭代器//PostOrder_iteratortemplate <class T>class BinaryTree<T>::PostOrder_iterator : public iterator { using iterator::pCurrent; using iterator::m_btree;public: PostOrder_iterator() {} PostOrder_iterator(const BinaryTree<T>& tree ) { m_btree = const_cast< BinaryTree<T>* >(&tree); GotoFirst(); //索引至第一个结点 } PostOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; pCurrent = iter.pCurrent; } PostOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); pCurrent = NULL; } else { pCurrent = const_cast< BTreeNode<T>* >(m_btree->GetRoot()); if( pCurrent != NULL ) { stk.Push(1); //节点计数进1 while( pCurrent->GetLeft() != NULL || pCurrent->GetRight() != NULL) { if( pCurrent->GetLeft() != NULL) { pCurrent = pCurrent->GetLeft(); stk.Push(1); } else if( pCurrent->GetRight() != NULL) { stk.Pop(); stk.Push(2); pCurrent = pCurrent->GetRight(); stk.Push(1); } } } } return *this; } bool IsEnd() { return pCurrent == NULL; } PostOrder_iterator& operator++() // 游标自增1 { if(IsEnd()) { return *this; } if( pCurrent->GetRight() == NULL || stk.GetTop() ==2) { pCurrent = pCurrent->GetParent(); stk.Pop(); } if( pCurrent != NULL && pCurrent->GetRight() != NULL && stk.GetTop() ==1) { //父节点存在右节点,且并未访问过 stk.Pop(); stk.Push(2); pCurrent = pCurrent->GetRight(); stk.Push(1); while( pCurrent->GetLeft() != NULL || pCurrent->GetRight() != NULL) { if( pCurrent->GetLeft() != NULL) { pCurrent = pCurrent->GetLeft(); stk.Push(1); } else if( pCurrent->GetRight() != NULL) { stk.Pop(); stk.Push(2); pCurrent = pCurrent->GetRight(); stk.Push(1); } } } return *this; } private: ChainStack<int> stk; //保存访问节点的遍历次数的栈};#endif
BinaryTree.cpp
#include "BinaryTree.h" #include <iostream> using namespace std; int main(){ BinaryTree<char> tree; //前序字符串 string str = "ABC#D##E#F##GH#I##JK##L##"; //后续字符串 //string str = "###DC###FEB###IH##K##LJGA"; //前序方法生成二叉树 tree.PreOrderCreateTree(str); cout << "EXP STR: " << str << endl; //前序方法遍历打印二叉树 tree.PreOrder(); //中序打印二叉树 tree.InOrder(); //后续打印二叉树 tree.PostOrder(); cout << "Tree Height:" << tree.Height() << endl; cout << "Tree Height:" << tree.Size() << endl; //二叉树拷贝构造调用 BinaryTree<char> tree2 = tree; tree2.PreOrder(); cout << "PreOrder iteraotr!/n"; //二叉树前序迭代器 BinaryTree<char>::PreOrder_iterator preiter(tree2); while(!preiter.IsEnd()) { cout << *preiter << ","; ++preiter; } cout << endl; //二叉树中序迭代器 tree.InOrder(); cout << "InOrder iteraotr!/n"; BinaryTree<char>::InOrder_iterator initer(tree2); while(!initer.IsEnd()) { cout << *initer << ","; ++initer; } //二叉树后续迭代器 cout << endl; tree2.PostOrder(); cout << "PostOrder iteraotr!/n"; BinaryTree<char>::PostOrder_iterator postiter(tree2); while(!postiter.IsEnd()) { cout << *postiter << ","; ++postiter; } return 0;}
- 二叉树完整实现C++
- 平衡二叉树的完整实现
- C++ 二叉树Tree类 完整实现
- 二叉搜索树数据结构完整实现
- 线索二叉树的完整代码实现
- 计算一棵完整二叉树的结点数 C实现
- 二叉树 c实现
- 二叉树 C实现
- 二叉树 c 实现
- 创建二叉查找树的完整C代码
- 二叉树完整练习
- Essential c++ 第六章二叉树的完整实现
- 完整类实现:构造,析构,遍历二叉树
- 二叉查找树 C++实现(含完整代码)
- 【二叉查找树】c实现
- 用c实现二叉树
- C语言实现二叉树
- 用c实现二叉树
- 二叉树叶子节点迭代器
- 调整android系统中的init.rc
- 正则表达式验证电话和邮箱格式示例
- 程序员的学习与积累
- Visual Studio中的正则替换
- 二叉树完整实现C++
- 有关cookie总是无法立即清除的原因
- 类加载机制
- IO系统性能之一:衡量性能的几个指标
- JSF框架AOM3.0中替换树组件
- MyEclipse6.5常用快捷键
- 从尾到头输出单链表
- 设计模式之适配器模式
- JsonHelper