【问题标题】:How is LinkedList's add(int, E) of O(1) complexity?LinkedList 的 add(int, E) 的 O(1) 复杂度如何?
【发布时间】:2013-03-21 20:55:11
【问题描述】:

来自标签维基摘录:

链表是一种数据结构,其中的元素包含 对下一个(也可以是前一个)元素的引用。链接 列表提供O(1) 在任意位置插入和删除,O(1) 列表 连接和 O(1) 访问在前面(和可选的后面) 位置以及 O(1) 下一个元素访问。随机访问有 O(N) 复杂且通常未实现。

(强调我的)

我很惊讶地看到这个 - 列表 insert 怎么能比简单地读取那个索引复杂度低?

所以我查看了the source code for java.util.LinkedListadd(int, E) method 是:

public void add(int index, E element) {
    addBefore(element, (index==size ? header : entry(index)));
}

addBefore(E, Entry<E> method 只是简单的指针重新分配,但还有entry(int) method

if (index < 0 || index >= size)
        throw new IndexOutOfBoundsException("Index: "+index+
                                            ", Size: "+size);
    Entry<E> e = header;
    if (index < (size >> 1)) {
        for (int i = 0; i <= index; i++)
            e = e.next;
    } else {
        for (int i = size; i > index; i--)
            e = e.previous;
    }
    return e;
}

即使使用半尺寸优化,这里的 for 循环(一个或另一个)在我看来是一个死的赠品,这种方法(因此 add(int, E))在 O 的最小最坏情况下运行(n) 时间,当然不是恒定的时间。

我错过了什么?我误解了大 O 符号吗?

【问题讨论】:

    标签: linked-list java linked-list big-o time-complexity


    【解决方案1】:

    好吧,它们确实支持在任意位置进行恒定时间插入——但只有在您碰巧有一个指向列表条目的指针,在该列表条目之后或之前要插入一些东西。当然,如果你只有索引,这是行不通的,但这不是你通常在优化代码中所做的。

    在 Java 中,您也可以这样做,但 only using a list iterator

    链表的这个属性是它们与数组列表相比最大的优势——例如,如果你想从聊天室的用户列表中删除一个用户,你可以存储一个指向用户在用户列表中位置的指针这样,当他想离开房间时,可以将其实现为O(1) 操作。

    【讨论】:

    • 换句话说:LinkedList&lt;E&gt;.add(int, E) 不是 O(1),但 ListIterator&lt;E&gt;.add 是(对于来自 LinkedList 的迭代器)。
    【解决方案2】:

    这是因为您正在阅读的文章将“获取该索引”视为单独的操作。本文假设您已经在您希望执行 add(int, E) 的索引处。

    总结:

    插入或删除操作 = O(1)

    在第 nth 索引处找到节点 = O(n)

    【讨论】:

    • 根据这个答案stackoverflow.com/a/18679284/4828060,在第n个索引处找到一个节点是O(1)。不确定我同意哪些答案:|
    • @JoãoMatos,这个特定的答案是对一个关于 addLast() 方法复杂性的问题的回答。由于 java 的 LinkedList 是一个双向链表,维护指向第一个和最后一个元素的指针,所以 addLast() 是 O(1)。在任意索引处查找节点仍然是 O(n)。
    【解决方案3】:

    链接新节点到任意节点的操作是O(1),但是查找(有助于循环)相关索引的操作肯定是O( n)。

    没有魔法;)

    【讨论】:

      【解决方案4】:

      你引用的维基页面说:

      O(1) 在任意位置插入和删除

      然后你问:

      读到这个我很惊讶——列表怎么能随机插入索引

      这就是混淆之处:术语 positionindex 并不是用来表示相同的东西。 wiki 讨论的是迭代器或指针,而不是索引。

      【讨论】:

      • 虽然position 有点模棱两可......并且“插入......在”暗示了索引解释。我已经建议了一个标签 wiki 编辑来澄清,你怎么看?
      • @thejh:我个人认为这很清楚。但是,鉴于至少有一个人对此感到困惑,我看不出稍微澄清会造成什么危害。
      猜你喜欢
      • 2017-12-26
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2016-04-21
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多