用C++实现二叉树

C++ 基础内容, 不值一提
Author:Jacky Wu       2006-5-15
引用该文章,必须注明其出处              http://blog.csdn.net/imwkj
 
 
二叉树是一个非常重要的数据结构,很多教材上并没有提到如何通过字符串或者其他形式来生成二叉树。
本人实现的二叉树类提供了如下功能
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_*/

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值