微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std::forward_list emplace_after O(1) 怎么样?

如何解决std::forward_list emplace_after O(1) 怎么样?

我目前正在实现一个前向列表(单链表)。 我注意到 std::forward_list::emplace_after 是 O(1),所以复杂度是恒定的:这怎么可能? 我问是因为:

  1. 你可以让新元素的位置在中间,
  2. 据我所知,找到必须添加新元素的位置的唯一方法是使用循环遍历列表。

我错过了什么吗? 这就是我目前实现该功能的方式。

constexpr void emplace_after(iterator position,Args...args) { // Must be O(1)
    size_type index_position = std::distance(begin(),position);

    Node* temp = m_head;
    for (size_type index{ 0 }; index < index_position; ++index) {
        temp = temp->next;
    }
    Node* next_temp = temp->next;
    Node* current_node = new Node(std::forward<Args>(args)...);
    temp->next = current_node;
    current_node->next = next_temp;

    temp = nullptr;
    next_temp = nullptr;
    m_size += 1;
}

这是我当前的前向迭代器实现:

template<typename T>
struct forward_iterator {
    Node* m_iterator;

    using value_type = T;
    using reference = value_type&;
    using pointer = value_type*;
    using iterator_category = std::forward_iterator_tag;
    using difference_type = std::ptrdiff_t;

    constexpr forward_iterator(Node* forw_iter = nullptr) : m_iterator{ forw_iter } {}

    constexpr Node* getNodeAddress() const noexcept {
        return m_iterator;
    }

    constexpr Node* getNodeNextAddress() const noexcept {
        return m_iterator->next;
    }

    constexpr reference operator*() const noexcept {
        return m_iterator->data;
    }

    constexpr pointer operator->() const noexcept {
        return m_iterator;
    }

    constexpr forward_iterator& operator++() noexcept {
        m_iterator = m_iterator->next;
        return *this;
    }

    constexpr forward_iterator operator++(int) noexcept {
        forward_iterator tmp(*this);
        this = (this)->next;
        return tmp;
    }

    constexpr friend bool operator== (const forward_iterator& first,const forward_iterator& second) noexcept {
        return (first.m_iterator == second.m_iterator);
    }

    constexpr friend bool operator!=(const forward_iterator& first,const forward_iterator& second) noexcept {
        return !(first.m_iterator == second.m_iterator);
    }
};

解决方法

您似乎对迭代器在单链表中的工作方式有误解。它们不仅仅是您可以(并且必须)搜索的标识符,它们应该以某种方式指向一个实际节点。

插图:

Iterator ------------------+
                           |
                           V 
[Head] -> Node -> Node -> Node -> Node -> Node -> nullptr

这意味着您的类 iterator 应该包含一个 Node *(编辑:因为它已经这样做了)

那么您的 emplace_back 可能如下所示:

constexpr void emplace_after(iterator position,Args... args)
{   
    Node* temp = position.getNodeAddress(); // retrieve the node position is referring

    Node* next_temp = temp->next;
    Node* current_node = new Node(std::forward<Args>(args)...);
    temp->next = current_node;
    current_node->next = next_temp;

    temp = nullptr;
    next_temp = nullptr;
    m_size += 1;
}
,

std::forward_list<T,Allocator>::emplace_after 的参数是一个迭代器,这意味着您需要在放置之前找到位置。因此,它只需要恒定的时间。

,

迭代器让你在 O(1) 时间内到达它们所指的节点。

如果您的迭代器没有,请修复它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。