【问题标题】:Time Complexity in singly link list单链表的时间复杂度
【发布时间】:2024-01-20 18:51:01
【问题描述】:

我正在研究数据结构:单链表。

网站说单链表的插入和删除时间复杂度为O(1)。我错过了什么吗?

website link

我在 C++ 中执行此操作,并且我只有一个 root pointer。如果我想在最后插入,那么我必须一直走到后面,这意味着O(n)

【问题讨论】:

标签: c++ data-structures linked-list time-complexity big-o


【解决方案1】:

这里认为你已经有了节点,之后你需要添加一个新元素。

在这种情况下,单链表插入时间复杂度变为 O(1)。

【讨论】:

    【解决方案2】:

    对此的解释是,链表中的大O表示法是指函数实现本身,不包括遍历链表以查找链表中的前一个引用节点。

    如果您点击Singly-LinkedList implementation 的*文章的链接,它会变得更加清晰:

    function insertAfter(Node node, Node newNode)
    function removeAfter(Node node)     
    

    上述函数签名已经将前置节点作为参数(隐式其他变体也是如此)。

    寻找前任是一个不同的操作,可能是 O(n) 或其他时间复杂度。

    【讨论】:

      【解决方案3】:

      我在 C++ 中执行此操作,并且我只有一个根指针。如果我想在最后插入,那么我必须一直走到后面,这意味着 O(n)。

      这是两个操作,您首先在列表中搜索 O(n) 给定位置,然后将 O(1) 元素插入列表中。

      在单链表中,插入操作包括:

      • 前一个元素的交替指针

      • 将对象包装到数据结构中并将其指针设置为下一个元素

      两者都不受列表大小的影响。

      另一方面,以 heap 结构为例。每个元素的插入需要 O(log(n)) 操作才能保留其结构。树结构具有类似的机制,将在插入时运行并取决于当前树的大小。

      【讨论】:

        【解决方案4】:

        您在两个地方错过了界面:

        1. std::list::insert()/std:list::erase() 需要一个迭代器指向要插入或擦除的元素。这意味着您无需搜索,仅更改列表中元素中的两个指针,这是恒定的复杂性。

        2. 可以通过 push_back 在列表末尾插入。该标准要求这也是 O(1)。这意味着,如果您有一个 std::list,它将存储第一个和最后一个元素。

        编辑:对不起,你遇到了 std::forward_list。即使名称是 insert_after 和 erase_after,第 1 点也适用。第 2 点不行,你必须迭代到列表的末尾。

        【讨论】: