从二叉搜索树中的 end() 迭代器递减迭代器
Posted
技术标签:
【中文标题】从二叉搜索树中的 end() 迭代器递减迭代器【英文标题】:Decrementing iterator from end() iterator in binary search tree 【发布时间】:2017-12-26 18:16:54 【问题描述】:在二叉搜索树中,end()
成员函数应该简单地返回 iterator(nullptr)
,对吧?但是节点nullptr
不包含有关其left
、right
和parent
数据的信息。那么我们如何从end()
中减少一个迭代器呢?以下是我到目前为止所拥有的(在iterator<T>
类中定义)。我的iterator<T>
类有node<T>* ptr
作为它唯一的数据成员,我的node<T>
类有成员T value; node *left, *right, *parent;
。
iterator& operator--()
// if (!ptr) what to do???
if (ptr->left)
ptr = node<T>::max_node(ptr->left);
else
node<T>* previous = ptr;
ptr = ptr->parent;
while (ptr && ptr->left == previous)
previous = ptr;
ptr = ptr->parent;
return *this;
【问题讨论】:
你回答了你自己的问题——如果你想能够递减(BidirectionIterator),那么显然end()
函数不能简单地返回nullptr,或者只包含一个nullptr的东西。相反,它必须返回一个指向某个标记的指针,该标记可以递减以指向最后一个元素。
Nullptr 如果你只想要一个不能递减的 ForwardIterator 就足够了。
【参考方案1】:
如果您希望您的迭代器成为双向迭代器,您需要提供必要的信息以在 end()
返回的迭代器中找到树的最后一个节点。为了避免处理特殊情况来减少 end()
迭代器,您可以使用“秘密”节点,该节点使用其左指针指向树的根。这样,end()
迭代器将只是一个指向此秘密节点的指针:使用这种方法,不需要在递增、递减或比较方面进行任何特殊处理。
由于通常不希望将节点值存储在根中,因此通常的实现将节点拆分为一个 NodeBase
,其中仅包含导航所需的指针,以及一个源自 NodeBase
并添加节点值的 NodeValue
.根使用NodeBase
成员和迭代器类型NodeBase*
:对于导航,只需要指针。由于只允许取消引用有效的迭代器,因此在访问节点的值时可以使用static_cast<NodeValue*>(n)
来获取NodeValue
。
【讨论】:
【参考方案2】:end() 不是 iterator(nullptr),而是 iterator(&anchor),其中 anchor 是包含树的成员,用于保存根开始和最终节点指针。然后要递减,您只需退回到前一个节点(递增的相反操作)。
它确实需要比简单地保存根节点指针更多的工作,但它也允许 begin() 和 end() 是 O(1) 操作。
【讨论】:
以上是关于从二叉搜索树中的 end() 迭代器递减迭代器的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode练习(Python):栈类:第173题:二叉搜索树迭代器:实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。 调用 next() 将返回二叉搜索树中的下一个最小的数。
Leetcode练习(Python):栈类:第173题:二叉搜索树迭代器:实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。 调用 next() 将返回二叉搜索树中的下一个最小的数。