我有点难以理解我是如何正确地做到这一点的,但是我需要能够在我正在实现的二进制搜索树类中增加一个迭代器,它使用模板。
迭代器的结构有一个当前节点,以及一个定义其当前位置的整数。我遇到的唯一问题是,当它进行++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但没有成功。我想使用它,因为这会让生活变得更轻松,但是现在我愿意编写自己的数据结构和算法。
至于迭代器,我猜我在设计中遗漏了一些东西,如果有人知道这可能是什么,请告诉我。如果有人要求的话,我很乐意为此发布整个课程的来源。
答案 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?左或右孩子?