【问题标题】:Decrementing iterator from end() iterator in binary search tree从二叉搜索树中的 end() 迭代器递减迭代器
【发布时间】: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 就足够了。

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


【解决方案1】:

如果您希望您的迭代器成为双向迭代器,您需要提供必要的信息以在 end() 返回的迭代器中找到树的最后一个节点。为了避免处理特殊情况来减少 end() 迭代器,您可以使用“秘密”节点,该节点使用其左指针指向树的根。这样,end() 迭代器将只是一个指向此秘密节点的指针:使用这种方法,不需要在递增、递减或比较方面进行任何特殊处理。

由于通常不希望将节点值存储在根中,因此通常的实现将节点拆分为一个 NodeBase,其中仅包含导航所需的指针,以及一个源自 NodeBase 并添加节点值的 NodeValue .根使用NodeBase 成员和迭代器类型NodeBase*:对于导航,只需要指针。由于只允许取消引用有效的迭代器,因此在访问节点的值时可以使用static_cast&lt;NodeValue*&gt;(n) 来获取NodeValue。

【讨论】:

    【解决方案2】:

    end() 不是 iterator(nullptr),而是 iterator(&anchor),其中 anchor 是包含树的成员,用于保存根开始和最终节点指针。然后要递减,您只需退回到前一个节点(递增的相反操作)。

    它确实需要比简单地保存根节点指针更多的工作,但它也允许 begin() 和 end() 是 O(1) 操作。

    【讨论】:

      猜你喜欢
      • 2015-01-18
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      相关资源
      最近更新 更多