为什么我们说链表插入是恒定时间?

时间:2016-10-03 17:24:53

标签: java algorithm linked-list time-complexity

据我所知,由于指针的简单重排,链接列表插入是恒定时间,但这不需要知道您从中插入的元素吗?

访问该元素需要线性搜索。那么为什么我们不说插入仍然首先受到线性搜索瓶颈的束缚?

编辑:我不是在讨论头部或尾部的附加物,而是在两者之间的任何位置进行插入。

3 个答案:

答案 0 :(得分:5)

是的,它需要已经有一个节点,您将在其旁边插入。

  

那么为什么我们不说插入仍然首先受到线性搜索瓶颈的束缚?

因为那不是必然的情况,如果你可以安排一些事实,你实际上知道插入点(不仅仅是索引,而是节点)。

显然你可以"插入"在前面或末尾,这似乎有点像作弊,它延伸了单词"插入"一点点。但请考虑另一种情况:当您追加到列表中时,您会记住某个节点。您选择的任何节点,使用任何标准来选择您想要的节点。然后,您可以稍后在该节点之后或之前轻松插入。

这听起来像一个非常"构建"情况,因为它。对于更加实际的情况(很不如此),您可以查看Dancing Links算法。

答案 1 :(得分:2)

  

为什么我们说链表插入是恒定时间?

因为 insert 操作是常量时间。

请注意,定位插入位置不被视为 insert 操作本身的一部分。这将是一个不同的操作,可能是也可能不是恒定时间,例如如果包含搜索时间,您将获得:

  • 在头部插入:常量
  • 在尾部插入:常量
  • 在迭代 1 时插入当前元素之前:常量
  • 在索引位置插入:线性

1)假设你无论如何都在迭代。

相比之下,ArrayList插入操作是线性时间。如果包含搜索时间,则会获得:

  • 在头部插入: 线性
  • 在尾部插入:常量(摊销)
  • 在迭代 1 时插入当前元素: 线性
  • 在索引位置插入:线性

答案 2 :(得分:1)

以下两项操作不同

  • 操作A:在链接列表中的任何位置插入

  • 操作B:插入链表中的特定位置

操作A可以在O(1)中实现。如果维护和期望,新元素可以插入head(或tail

操作B涉及查找,然后插入。查找部分为O(n)。插入如上,即O(1)。但是,如果将结果作为输入提供,例如,如果存在类似

的API
Node * Find(Node * head, int find_property);
Node * InsertAfter(Node * head, Node * existing_node, Node * new_node);

然后操作的插入部分为O(1)