增加BST的迭代器

时间:2012-05-11 18:49:43

标签: c++ iterator binary-search-tree

我有点难以理解我是如何正确地做到这一点的,但是我需要能够在我正在实现的二进制搜索树类中增加一个迭代器,它使用模板。

迭代器的结构有一个当前节点,以及一个定义其当前位置的整数。我遇到的唯一问题是,当它进行++Iter操作时,我该如何确定它是向左还是向左?

这是整个班级的头文件:

template < typename TComparable, typename TValue > 
    class SearchTree
    {
    public:
        class Iterator;
    private:
        struct Node;
        typedef typename Node TNode;
    public:
        SearchTree( void );
        ~SearchTree( void );
    public:
        TValue find( const TComparable& k );
        TValue find( int32_t index );
        TValue find( const Iterator& pIter );

        Iterator begin( void ) const;
        Iterator end( void ) const;

        void insert( const TComparable& k, const TValue& v );
        void insert( const Iterator& pIter );

        friend class Iterator;
        friend class TNode;
    private:
        int32_t mNodeCount;
        TNode* mRoot;
    public:
        class Iterator 
        {
        public:
            Iterator( void );
            Iterator( int32_t position );
            ~Iterator( void );
            inline TNode* operator->( void ) const 
            { return mCurrentNode; }
            void operator++( void );
            bool operator==( const Iterator& pIter );
            bool operator!=( const Iterator& pIter );
        private:
            int32_t getNumStepsLeftToLeaf( void );
            int32_t getNumStepsRightToLeaf( void );
            bool isLeafNode( const Node*& n );
            bool isInternalNode( const Node*& n );
        private:
            TNode* mCurrentNode;
            int32_t mIterPosition;
            friend class TNode;
        };
    private:
        struct Node
        {
        public:
            Node( void ) : mParent( NULL ), mLeftChild( NULL ), mRightChild( NULL )
            {}
            ~Node( void )
            {
                if ( mParent ) delete mParent;
                if ( mLeftChild ) delete mLeftChild;
                if ( mRightChild ) delete mRightChild;
            }
            int32_t index;
            TComparable Key;
            TValue Value;
            TNode* mParent;
            TNode* mLeftChild;
            TNode* mRightChild;
        };
    };

请注意,我不能为此使用异常,因为我计划将大量此代码移植到Android NDK,我认为不能使用STLport的异常(这将是我将使用的 - GnuSTL是GPL'd,意味着我正在做什么(这是为了获利)我不能使用它 - 如果有人有任何可以与之相矛盾的东西,请告诉我)

此外,在任何人提到提升之前,我已经尝试将其移植到NDK但没有成功。我想使用它,因为这会让生活变得更轻松,但是现在我愿意编写自己的数据结构和算法。

至于迭代器,我猜我在设计中遗漏了一些东西,如果有人知道这可能是什么,请告诉我。如果有人要求的话,我很乐意为此发布整个课程的来源。

1 个答案:

答案 0 :(得分:1)

首先,前缀增量运算符具有以下签名:

Iterator& operator++();

并且应该以这种方式根据前缀声明和定义后缀:

const Iterator& operator++(int){Iterator old = *this; ++(*this); return old;}

您可能希望前缀向其节点询问下一个(最左侧)节点

Iterator& Iterator::operator++(){
    myParent = mCurrentNode; 
    return  myParent.getRightOf(mCurrentNode); 
}

你看,我认为你有办法从一个你可能至少应该拥有的节点构造一个迭代器 私人的。

我想你想要遍历叶子节点,(无论如何内部节点的实现并不相同)。 您需要或多或少地执行以下getRightOf方法,让我为它写下一些伪代码:

Node* Node::getRightOf(Node* aNode){ 
    if aNode == mLeftChild{
        if mRightNode
            return mRightNode(this); 
        return mParent(this)
    }
    if aNode == mRightChild{
        return mParent(this)
    }
    if aNode == mParent{
        if mLeftNode
            return mLeftNode(this); 
        if mRightNode
            return mRightNode(this); 
        return this; 
    }
}

您需要注意管理容器末尾的迭代等案例。

警告

在Node的析构函数中,我读到了:

if ( mParent ) delete mParent;

这看起来很危险:谁删除了ParentNode?左或右孩子?