用C++实现二叉树(转)
2009-04-20 14:14
417 查看
二叉树是一个非常重要的数据结构,很多教材上并没有提到如何通过字符串或者其他形式来生成二叉树。 本人实现的二叉树类提供了如下功能 1:由前序字串生成二叉树 2:由后续字串生成二叉树 3:提供三种迭代器,用于遍历二叉树 文件 test.cpp 是对二叉树接口的测试,文件BinaryTree.h是二叉树模板的实现,其中用到了链栈,myStack.h 在以前的文章提到过,并且也提供了代码 在BinaryTree.h 定义了几个类 BinTreeNode :二叉树节点类,带父节点 BinaryTree : 二叉树类 BinaryTree::iterator; //迭代器基类 BinaryTree::PreOrder_iterator; //前序迭代器 BinaryTree::InOrder_iterator; //中序迭代器 BinaryTree::PostOrder_iterator; //后序迭代器 * Copyright (c) 2006 * Jacky Wu * You can use these source code for any purpose. * And It is provided "as is" without express or implied warranty. * * 你可以任意使用该代码,但是本人不对代码的安全性做任何担保!!! * * 由于大部分代码是出于学习目的实现的,只是让它“可以使用", * 并没有经过安全性,高负荷运行强度等测试,我必须对这些代码做一个声明: * !!!! * 免责声明: * 对于使用在本blog上提供的任意“形式”(包括测试,类的实现, * 系统的分析 等等只要是代码片断)的代码造成系统不稳定或者 * 由于此造成的经济、声誉上的损失,或者是人身伤害等任何损失,本人不负任何法律责任 |
//文件 test.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; } |
//文件BinaryTree.h #ifndef BINARYTREE_H_ #define BINARYTREE_H_ #include "myStack.h" #include <string> #include <iostream> #include <stdexcept> enum ChildID { LEFTCHILD = 0, RIGHTCHILD }; //子节点类型,是左节点还是右节点 template <class Type> class BinaryTree; //愚认为,如果BinTreeNode中的数据需要让大部分用户访问的话,应当是struct型 template <class Type> class BinTreeNode { friend class BinaryTree< Type >; public: BinTreeNode() : m_pParent(0), m_plChild(0), m_prChild(0){} BinTreeNode( Type item, BinTreeNode<Type> *parent = 0, BinTreeNode<Type> *left = 0, BinTreeNode<Type> *right = 0 ) : m_pParent(parent), m_plChild(left), m_prChild(right), m_data(item) {} Type GetData() const; //获取节点保存的数据 Type& GetDataRef(); //不应当提供这样的接口,这里仅仅让iterator能够自由访问存储的数据 BinTreeNode* GetParent() const; //获取节点的父节点 BinTreeNode* GetLeft() const; //获取节点的左子节点 BinTreeNode* GetRight() const; //获取节点的右子节点 void SetData( const Type& data ); //修改节点的数据 //下面是更改节点的指针域结构的function,是否真的需要,还得仔细考量 //做为树的节点,一般不允许直接访问节点中的指针数据,如果这些数据在树 //被建立完成以后修改,会破坏树的结构 void SetParent( BinTreeNode<Type>* parent, ChildID CHID ); //设置当前节点的父节点,并指定当前节点作为子节点的类型 void SetLeft( BinTreeNode<Type>* left); //设置当前节点的左子节点 void SetRight( BinTreeNode<Type>* right); //设置当前节点的右子节点 private: BinTreeNode< Type >* m_pParent; //父节点 BinTreeNode< Type >* m_plChild; //left Child BinTreeNode< Type >* m_prChild; //right Child Type m_data; }; //declare BinTreeNode end //********************************************************* // BinTreeNode Implementation //********************************************************* template <class Type> Type BinTreeNode<Type>::GetData() const { return m_data; } template <class Type> Type& BinTreeNode<Type>::GetDataRef() { return m_data; } template <class Type> BinTreeNode<Type>* BinTreeNode<Type>::GetParent() const { return m_pParent; } template <class Type> BinTreeNode<Type>* BinTreeNode<Type>::GetLeft() const { return m_plChild; } template <class Type> BinTreeNode<Type>* BinTreeNode<Type>::GetRight() const { return m_prChild; } template <class Type> void BinTreeNode<Type>::SetData( const Type& data ) { m_data = data; } template <class Type> void BinTreeNode<Type>::SetParent( BinTreeNode<Type>* parent, ChildID CHID ) { if( !parent ) return; if( CHID == m_plChild ) //当前节点作为parent的左子节点 { m_pParent = parent; parent->m_plChild = this; } else if( CHID == RIGHTCHILD ) //当前节点作为parent的右子节点 { m_pParent = parent; parent->m_prChild = this; } } template <class Type> void BinTreeNode<Type>::SetLeft( BinTreeNode<Type>* left) { m_plChild = left; } template <class Type> void BinTreeNode<Type>::SetRight( BinTreeNode<Type>* right) { m_prChild = right; } // BinTreeNode Implementation over //********************************************************* //********************************************************* template <class Type> class BinaryTree { public: BinaryTree() : root(NULL) {} BinaryTree( Type value) : RefValue(value), root(NULL) {} BinaryTree( const BinaryTree<Type>& tree); //copy Constructure privated BinaryTree<Type>& operator=( const BinaryTree<Type>& tree); //operator= privated virtual ~BinaryTree(); virtual int IsEmpty() { return root == NULL; } /* * 下面三个函数的可用性,返回值类型的正确性值得考量 * 这样做不仅会破坏树的结构,而且很容易引起内存泄漏 * 在一般的树中最好不要提供这三个接口 */ virtual BinTreeNode<Type>* Parent( BinTreeNode<Type>* current ); //返回所给结点父结点 virtual BinTreeNode<Type>* LeftChild( BinTreeNode<Type>* current); //返回节点的左子积极淡 virtual BinTreeNode<Type>* RightChild( BinTreeNode<Type>* current); //返回节点的右子女 virtual bool Insert( const Type& item); //插入元素 virtual bool Find( const Type& item) const; //搜索元素 const BinTreeNode<Type>* GetRoot() const; //取树根 //遍历操作 void PreOrder() const; //前序 void InOrder() const; //中序 void PostOrder() const; //后序 //二叉树特性操作函数 int Size() const; int Size( const BinTreeNode<Type>* troot) const; int Height() const; int Height( const BinTreeNode<Type>* troot) const; bool operator==( const BinaryTree<Type>& tree) const; //下面的接口是以不同的方式来构建二叉树 BinaryTree<Type>& AutoCreateTree(const std::string& expstr); //自动判断格式并建立 BinaryTree<Type>& PreOrderCreateTree(const std::string& expstr); //先序建立 BinaryTree<Type>& PostOrderCreateTree(const std::string& expstr); //后续建立 protected: BinTreeNode< Type>* Parent( BinTreeNode<Type>* start, BinTreeNode<Type>* current ); int Insert( BinTreeNode<Type>* current, const Type& item); void Travers( BinTreeNode<Type>* current, std::ostream& out ) const; void Find( BinTreeNode<Type>* current, const Type& item ) const; void destroy( BinTreeNode<Type>* current); //遍历递归 void InOrder( BinTreeNode<Type>* current) const; void PreOrder( BinTreeNode<Type>* current ) const; void PostOrder( BinTreeNode<Type>* current) const; //二叉树特性递归操作函数 BinTreeNode<Type>* Copy( BinTreeNode<Type>* troot, BinTreeNode<Type>* parent); bool equal( BinTreeNode<Type>* troot1, BinTreeNode<Type>* troot2) const; //建树用的递归函数 BinTreeNode<Type>* PreOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent); //先序递归建立二叉树 BinTreeNode<Type>* PostOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent); //后续递归建立二叉树 //声明一组用于二叉树的迭代器iterator private: 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: BinTreeNode< Type >* root; //树的根指针 Type RefValue; //数据输入终结标志 }; //END BinaryTree /********************************** * implament of template BinaryTree * **********************************/ template <class Type> BinaryTree<Type>::BinaryTree( const BinaryTree<Type>& tree) //copy Constructure privated { root = Copy(tree.root, NULL); } template <class Type> BinaryTree<Type>& BinaryTree<Type>::operator=( const BinaryTree<Type>& tree) //operator= privated { destroy(root); root = Copy(tree.root, NULL); return *this; } template <class Type> BinaryTree<Type>::~BinaryTree() { destroy(root); //遍历删除二叉树 } template <class Type> bool BinaryTree<Type>::Insert( const Type& item) { return true; } template <class Type> bool BinaryTree<Type>::Find( const Type& item) const { return true; } template <class Type> BinTreeNode<Type>* BinaryTree<Type>::Parent( BinTreeNode<Type>* current) { if( root == NULL || root == current ) { return NULL; } else { return current->m_pParent; } /* * 由于节点保留了parent的地址,所以可以直接取得父节点的地址 * 但是节点中如果没有parent的数据,就必须调用递归查询来寻找父节点的地址 * 代码片断如下,它调用了Parent( BinTreeNode<Type> *start, BinTreeNode<Type>* current) return (root == NULL || root == current) ? NULL : Parent( root, current); */ } template <class Type> BinTreeNode<Type>* BinaryTree<Type>::LeftChild( BinTreeNode<Type>* current) { return current != NULL ? current->m_plChild : NULL; } template <class Type> BinTreeNode<Type>* BinaryTree<Type>::RightChild( BinTreeNode<Type>* current) { return current != NULL ? current->m_prChild : NULL; } template <class Type> BinTreeNode<Type>* BinaryTree<Type>::Parent( BinTreeNode<Type> *start, BinTreeNode<Type>* current) { //从结点start开始,搜索节点current的父结点, //如果找到其父节点,则函数将其返回,否则返回 NULL if( !start ) return NULL; if( start->m_plChild == current || start->m_prChild == current) return start; BinTreeNode<Type> *pNode; if((pNode = Parent( start->m_plChild, current)) != NULL) { return pNode; } else { return Parent( start->m_prChild, current); } } template <class Type> const BinTreeNode<Type>* BinaryTree<Type>::GetRoot() const { return root; } template <class Type> void BinaryTree<Type>::Travers( BinTreeNode<Type>* current, std::ostream& out) const { //前序输出根为current的二叉数 if( current ) { out << current->m_data; Travers( current->m_plChild , out ); Travers( current->m_prChild, out ); } else { out<<"#"; } } //中序遍历操作 template <class Type> void BinaryTree<Type>::InOrder() const { std::cout << "InOrder Traval Tree:/n"; InOrder( root ); std::cout << std::endl; } template <class Type> void BinaryTree<Type>::InOrder( BinTreeNode<Type>* current) const { //递归私有函数,中序遍历二叉树 if(current != NULL) { InOrder(current->m_plChild); std::cout << current->m_data; InOrder(current->m_prChild); } else { std::cout << "#"; } } //前序遍历操作 template <class Type> void BinaryTree<Type>::PreOrder() const { std::cout << "PreOrder Travel Tree:/n"; PreOrder (root); std::cout << std::endl; } template <class Type> void BinaryTree<Type>::PreOrder( BinTreeNode<Type>* current) const { if(current != NULL) { std::cout << current->m_data; PreOrder(current->m_plChild); PreOrder(current->m_prChild); } else { std::cout <<"#"; } } //后序遍历操作 template <class Type> void BinaryTree<Type>::PostOrder() const { //后序遍历 std::cout << "PostOrder Travel Tree:/n"; PostOrder(root); std::cout << std::endl; } template <class Type> void BinaryTree<Type>::PostOrder( BinTreeNode<Type>* current) const{ //后序递归操作 if( current != NULL ) { PostOrder(current->m_plChild); PostOrder(current->m_prChild); std::cout << current->m_data; } else { std::cout << "#"; } } //计算二叉树的结点数 template <class Type> int BinaryTree<Type>::Size() const { return Size(root); } template <class Type> int BinaryTree<Type>::Size( const BinTreeNode<Type>* troot) const { if(troot == NULL) return 0; //空树,返回0 else return 1 + Size(troot->m_plChild) + Size(troot->m_prChild); } //计算二叉树的高度 template <class Type> int BinaryTree<Type>::Height() const { return Height(root); } template <class Type> int BinaryTree<Type>::Height( const BinTreeNode<Type>* troot) const { if ( troot == NULL ) return -1; else return 1 + MAX( Height( troot->m_plChild ) , Height( troot->m_prChild) ); } //用于递归拷贝的私有函数 template <class Type> BinTreeNode<Type>* BinaryTree<Type>::Copy( BinTreeNode<Type>* troot, BinTreeNode<Type>* parent) { if (NULL == troot) return NULL; BinTreeNode<Type>* pNode = new BinTreeNode<Type>; pNode->m_data = troot->m_data; //拷贝数据 pNode->m_pParent = parent; pNode->m_plChild = Copy( troot->m_plChild, pNode ); //新建左子树 pNode->m_prChild = Copy( troot->m_prChild, pNode ); //新建右子树 return pNode; //返回树根结点 } //判断二叉树内容是否相等 template <class Type> bool BinaryTree<Type>::operator==( const BinaryTree<Type>& tree) const { return equal( root, tree.root ); } //判断二叉树相等的递归操作 template <class Type> bool BinaryTree<Type>::equal( BinTreeNode<Type>* troot1, BinTreeNode<Type>* 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->m_plChild, troot2->m_plChild) && equal( troot1->m_prChild, troot2->m_prChild); } return true; } template <class Type> void BinaryTree<Type>::destroy( BinTreeNode<Type>* current) { if( current ) { destroy( current->m_plChild ); //递归删除左结点 destroy( current->m_prChild); //除右节点 delete current; current = NULL; //空置指针 } } //define of Max function template <class _T> _T MAX(const _T& a, const _T& b) { return (a>=b) ? a : b; } //********************************************************* //1:先序方式建立二叉树 template <class Type> BinaryTree<Type>& BinaryTree<Type>::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 Type> BinTreeNode<Type>* BinaryTree<Type>::PreOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent) { if( *expstr == '#' || *expstr == '/0') return NULL; BinTreeNode<Type>* pnewNode = new BinTreeNode<Type>(*expstr, parent); assert(pnewNode); pnewNode->m_plChild = PreOrderCreateNode(++expstr, pnewNode); pnewNode->m_prChild = PreOrderCreateNode(++expstr, pnewNode); return pnewNode; } //********************************************************* //********************************************************* //3:后续方式建立二叉树 template <class Type> BinaryTree<Type>& BinaryTree<Type>::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 Type> BinTreeNode<Type>* BinaryTree<Type>::PostOrderCreateNode(const char* &expstr, BinTreeNode<Type>* parent) { if( *expstr == '#') return NULL; BinTreeNode<Type>* pnewNode = new BinTreeNode<Type>(*expstr, parent); assert(pnewNode); pnewNode->m_prChild = PostOrderCreateNode(--expstr, pnewNode); pnewNode->m_plChild = PostOrderCreateNode(--expstr, pnewNode); return pnewNode; } //******************************************************** //******************************************************** //三种迭代器的实现 //iterator 是私有的基类迭代器,这里没有实现常量树的迭代器 const_iterator //这样做确保了用户不可能访问到这个迭代器 template <class Type> class BinaryTree<Type>::iterator { public: iterator():m_btree(NULL), m_pCurrent(NULL){} virtual ~iterator() {} virtual iterator& operator= (const iterator& iter) { m_pCurrent = iter.m_pCurrent; return *this; } virtual iterator& GotoFirst() = 0; //游标索引到第一个节点 virtual bool IsEnd() = 0; //游标是否已经索引到末尾 virtual iterator& operator++() = 0; // 游标自增 //virtual iterator operator++(int) = 0; virtual const Type& current() const; virtual Type& operator*(); virtual Type* operator->(); protected: BinaryTree<Type>* m_btree; BinTreeNode<Type>* m_pCurrent; }; template <class Type> const Type& BinaryTree<Type>::iterator::current() const { if(m_pCurrent != NULL) { return m_pCurrent->GetDataRef(); } else { throw std::out_of_range("iterator error/n"); } } template <class Type> Type& BinaryTree<Type>::iterator::operator*() { if(m_pCurrent != NULL) { return m_pCurrent->GetDataRef(); } else { throw std::out_of_range("iterator error/n"); } } template <class Type> Type* BinaryTree<Type>::iterator::operator->() { if(m_pCurrent != NULL) { return &(m_pCurrent->GetDataRef()); } else { throw std::out_of_range("iterator error/n"); } } //********************************************************* //这里采用两种方式来遍历树 //1:采用简单计数栈的非递归遍历(要求结点中有父节点数据域) //2:采用栈的非递归遍历(在最后注释部分) //********************************************************* //前序遍历迭代器(无栈) template <class Type> class BinaryTree<Type>::PreOrder_iterator : public iterator { using iterator::m_pCurrent; using iterator::m_btree; public: PreOrder_iterator() {} PreOrder_iterator(const BinaryTree<Type>& tree ) { m_btree = const_cast< BinaryTree<Type>* >(&tree); GotoFirst(); //索引至第一个结点 } PreOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; m_pCurrent = iter.m_pCurrent; } PreOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); m_pCurrent = NULL; } else { m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot()); //强制转换为非常量指针 stk.Push(1); //记录当前树的根节点访问次数 } return *this; } bool IsEnd() { return m_pCurrent == NULL; } PreOrder_iterator& operator++() ; // 游标自增 //PreOrder_iterator operator++(int); private: ChainStack<int> stk; //保存访问节点的遍历次数的栈 }; template <class Type> typename BinaryTree<Type>::PreOrder_iterator& BinaryTree<Type>::PreOrder_iterator::operator++() //前序后继节点 { if( stk.IsEmpty() ) //确保迭代器是有效的 { return *this; } //访问左子节点 if( m_pCurrent->GetLeft() == NULL) //左节点无效 { stk.Pop(); stk.Push(2); //m_pCurrent 第二次访问 //查询右节点 if( m_pCurrent->GetRight() == NULL) //右节点也无效 { //回溯搜索有效的节点 while( !stk.IsEmpty() && stk.Pop()==2 ) { m_pCurrent = m_pCurrent->GetParent(); } stk.Push(1); //节点的右子节点不可访问,继续回溯,搜索到跟节点,停止搜索 while(m_pCurrent != NULL && m_pCurrent->GetRight() == NULL ) { m_pCurrent = m_pCurrent->GetParent(); stk.Pop(); } //如果已经搜索出根节点,抛出异常 if(m_pCurrent == NULL) { //throw std::out_of_range("BinaryTree iterator over/n"); } else { stk.Pop(); stk.Push(2); //m_pCurrent访问计数2 m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); } } else //右节点有效 { m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); } } else //左节点有效 { m_pCurrent = m_pCurrent->GetLeft(); stk.Push(1); } return *this; } //中序遍历迭代器 //InOrder_iterator template <class Type> class BinaryTree<Type>::InOrder_iterator : public iterator { using iterator::m_pCurrent; using iterator::m_btree; public: InOrder_iterator() {} InOrder_iterator(const BinaryTree<Type>& tree ) { m_btree = const_cast< BinaryTree<Type>* >(&tree); GotoFirst(); //索引至第一个结点 } InOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; m_pCurrent = iter.m_pCurrent; } InOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); m_pCurrent = NULL; } else { m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot()); if( m_pCurrent != NULL ) { stk.Push(1); //节点计数进1 while( m_pCurrent->GetLeft() != NULL ) { m_pCurrent = m_pCurrent->GetLeft(); stk.Push(1); } } } return *this; } bool IsEnd() { return m_pCurrent == NULL; } InOrder_iterator& operator++() // 游标自增1 { if(IsEnd()) { return *this; } if( m_pCurrent->GetRight() == NULL) { stk.Pop(); stk.Push(2); while( !stk.IsEmpty() && stk.Pop() == 2) { m_pCurrent = m_pCurrent->GetParent(); } stk.Push(2); return *this; } else { //右节点有效 stk.Pop(); stk.Push(2); m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); while( m_pCurrent->GetLeft() != NULL) { m_pCurrent = m_pCurrent->GetLeft(); stk.Push(1); } } return *this; } //InOrder_iterator operator++(int); private: ChainStack<int> stk; //保存访问节点的遍历次数的栈 }; //********************************************************** //后序遍历迭代器 //PostOrder_iterator template <class Type> class BinaryTree<Type>::PostOrder_iterator : public iterator { using iterator::m_pCurrent; using iterator::m_btree; public: PostOrder_iterator() {} PostOrder_iterator(const BinaryTree<Type>& tree ) { m_btree = const_cast< BinaryTree<Type>* >(&tree); GotoFirst(); //索引至第一个结点 } PostOrder_iterator(const PreOrder_iterator& iter) { m_btree = iter.m_btree; m_pCurrent = iter.m_pCurrent; } PostOrder_iterator& GotoFirst() { stk.MakeEmpty(); if(m_btree == NULL) { stk.MakeEmpty(); m_pCurrent = NULL; } else { m_pCurrent = const_cast< BinTreeNode<Type>* >(m_btree->GetRoot()); if( m_pCurrent != NULL ) { stk.Push(1); //节点计数进1 while( m_pCurrent->GetLeft() != NULL || m_pCurrent->GetRight() != NULL) { if( m_pCurrent->GetLeft() != NULL) { m_pCurrent = m_pCurrent->GetLeft(); stk.Push(1); } else if( m_pCurrent->GetRight() != NULL) { stk.Pop(); stk.Push(2); m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); } } } } return *this; } bool IsEnd() { return m_pCurrent == NULL; } PostOrder_iterator& operator++() // 游标自增1 { if(IsEnd()) { return *this; } if( m_pCurrent->GetRight() == NULL || stk.GetTop() ==2) { m_pCurrent = m_pCurrent->GetParent(); stk.Pop(); } if( m_pCurrent != NULL && m_pCurrent->GetRight() != NULL && stk.GetTop() ==1) { //父节点存在右节点,且并未访问过 stk.Pop(); stk.Push(2); m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); while( m_pCurrent->GetLeft() != NULL || m_pCurrent->GetRight() != NULL) { if( m_pCurrent->GetLeft() != NULL) { m_pCurrent = m_pCurrent->GetLeft(); stk.Push(1); } else if( m_pCurrent->GetRight() != NULL) { stk.Pop(); stk.Push(2); m_pCurrent = m_pCurrent->GetRight(); stk.Push(1); } } } return *this; } private: ChainStack<int> stk; //保存访问节点的遍历次数的栈 }; #endif /*BINARYTREE_H_*/ |
相关文章推荐
- 【c++】c++模板类,实现二叉树非递归遍历
- C++实现二叉树的递归遍历与非递归遍历(先序、中序、后序、层序)
- 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]
- C++ 二叉树的实现
- [置顶] 二叉树的建立、节点查找以及节点删除C和C++实现
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- C++实现二叉树
- 二叉树的C++实现
- C++模板实现二叉树(六 AVL树基础与旋转)
- 二叉树的建立与遍历(二)(c++实现)
- 二叉树完整实现C++
- c++实现二叉树的查找,插入,删除,深度,叶子节点数,度为1的节点数(递归方法)及运行实例结果
- c++实现二叉树的查找,插入,删除,深度,叶子节点数,度为1的节点数(递归方法)及运行实例结果
- C++实现二叉树基本操作详解
- 【头文件】c++实现二叉树
- 用C++实现二叉树
- 二叉树的线索化(C++实现)
- C++模板实现二叉树(五 树的平衡之dsw算法)
- 二叉树数组C++实现