【问题标题】:std::list, move item in list using iterators onlystd::list,仅使用迭代器移动列表中的项目
【发布时间】:2017-10-29 21:34:38
【问题描述】:

根据我对链表的了解,在我看来这应该是可能的,但我还没有找到任何有答案的地方,所以我在这里问。

给定两个迭代器到同一个列表中的项目。我想将迭代器“frm”指向的项目“插入”到迭代器“to”指向的项目之前的列表中。

似乎只需要更改列表中指向“frm”的项目的指针(以删除“frm”),然后更改指向“to”的项目的指针,以便它引用“frm”然后将“frm”节点上的指针更改为指向“to”。

我到处寻找这个问题,但找不到答案。

请注意,我不能使用 splice,因为我无法访问列表,只能访问列表中项目的迭代器。

template <typename T>
void move(typename std::list<T>::iterator frm, typename std::list<T>::iterator to) {
    //remove the item from the list at frm

    //insert the item at frm before the item at to
}

【问题讨论】:

  • 在不知道它属于哪个容器的情况下,不能使用迭代器将自己从容器中移除。它也不能用于将新项目附加到容器中。迭代器不一定知道它们属于哪个容器。

标签: c++ list linked-list iterator std


【解决方案1】:

迭代器包含指向一条数据所需的最少信息,您所缺少的是链表还有其他与之相伴的簿记,所以基本上list 类看起来像下面这样

template <typename Type>
class list {
    int size; // for O(1) size()
    Type* head;
    Type* tail;

    class Iterator {
        Type* element;
        // no back pointer to list<Type>*
    };
    ...
};

要从列表中删除一个元素,您还需要更新这些数据成员。为此,迭代器必须包含指向列表本身的反向指针,根据为大多数迭代器提供的接口,这不是必需的。另请注意,STL 中的算法实际上并没有修改操作容器的簿记,只是可能交换元素并重新排列事物。

我鼓励您查看&lt;algorithm&gt; 标头以及std::back_inserterstd::move_iterator 等设施,以了解如何包装迭代器以实际修改它们所代表的容器。

【讨论】:

    【解决方案2】:

    它的实现是实现定义的,但是 c++ 标准允许使用 iter_swap,尽管它并没有完全做到这一点。这可能会优化为交换链接列表中保存的值上的指针,类似于我所描述的有效地重新排序列表中的项目而无需完全交换。

    iter_swap() versus swap() -- what's the difference?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多