zoukankan      html  css  js  c++  java
  • [转]二叉树的实现

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

  • 相关阅读:
    angular安装指定版本
    Fluttter通过按钮来打开抽屉Drawer或者endDrawer
    angular中的animation动画
    flutter pubspec.yaml配置文件详解
    angular-cli卸载安装
    angular的项目基本配置的了解
    angular使用代理解决跨域
    IOS开发之UI布局
    用Objective-C写了一个简单的批量更改文件名的程序
    使用Objective-C 计算代码运行时间
  • 原文地址:https://www.cnblogs.com/tangtang-123/p/4437019.html
Copyright © 2011-2022 走看看