在Java中,为什么在链表中插入或删除是一个常量时间操作?这不是误导吗?

2022-09-04 07:41:23

在列表的特定点插入或删除元素(假设我们已经有指向该节点的指针)是一个常量时间操作。- 来自链接列表上的维基百科条目

单个链表中的链接列表遍历始终从头部开始。我们必须继续前进,直到我们满足一个给定的条件。

因此,这将使任何操作最坏的情况O(n),除非我们正在处理头节点。

我们不能直接转到链接列表中的给定指针。那么为什么说它是一个恒定时间操作呢?

编辑:即使我们有一个指向节点的指针,我们也只能从头部开始对吧?那么它是如何进行恒定时间操作的


答案 1

首先:在Sun JDK中实现的实际上具有指向最后一个元素以及第一个元素的链接(只有一个条目,但指向最后一个元素)。这意味着,即使在最坏的情况下,在列表中导航到索引指示的元素也应该执行 n/2 操作。它也是一个双重链接列表。LinkedListheadhead.previous

除此之外:插入到 a 的开头或结尾是微不足道的 O(1),因为你不需要遍历所有元素。LinkedList

插入/删除其他任何地方取决于您的确切操作方式!如果您使用迭代器(用于添加的ListIterator),则该操作也可以是O(1),因为将已经具有对相关条目的引用。Iterator

但是,如果您使用的是 add(int, E)remove(int),则必须找到相关条目 (O(n)),然后删除元素 (O(1)),因此整个操作将为 O(n)。LinkedList


答案 2

你自己说过:“假设我们已经有一个指向节点的指针”。这避免了您确定为线性时间原因的遍历。

诚然,维基百科的文本有点含糊不清,因为涉及两个节点:插入的节点和列表中插入的节点。


推荐