[轉]二叉樹的實現

(C++)ios

實現的二叉樹類提供了以下功能express

1:由前序字串生成二叉樹安全

2:由後續字串生成二叉樹ide

3:提供三種迭代器,用於遍歷二叉樹函數

文件 test.cpp 是對二叉樹接口的測試,文件BinaryTree.h是二叉樹模板的實現,其中用到了鏈棧,myStack.h 在之前的文章提到過,而且也提供了代碼post

 

在BinaryTree.h 定義了幾個類學習

BinTreeNode :二叉樹節點類,帶父節點測試

BinaryTree : 二叉樹類this

BinaryTree::iterator;       //迭代器基類spa

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

{

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

相關文章
相關標籤/搜索