用C++实现二叉树(转)

二叉树是一个非常重要的数据结构,很多教材上并没有提到如何通过字符串或者其他形式来生成二叉树。

本人实现的二叉树类提供了如下功能

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 == NULLreturn 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_*/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值