据我所知,由于指针的简单重排,链接列表插入是恒定时间,但这不需要知道您从中插入的元素吗?
访问该元素需要线性搜索。那么为什么我们不说插入仍然首先受到线性搜索瓶颈的束缚?
编辑:我不是在讨论头部或尾部的附加物,而是在两者之间的任何位置进行插入。
答案 0 :(得分:5)
是的,它需要已经有一个节点,您将在其旁边插入。
那么为什么我们不说插入仍然首先受到线性搜索瓶颈的束缚?
因为那不是必然的情况,如果你可以安排一些事实,你实际上知道插入点(不仅仅是索引,而是节点)。
显然你可以"插入"在前面或末尾,这似乎有点像作弊,它延伸了单词"插入"一点点。但请考虑另一种情况:当您追加到列表中时,您会记住某个节点。您选择的任何节点,使用任何标准来选择您想要的节点。然后,您可以稍后在该节点之后或之前轻松插入。
这听起来像一个非常"构建"情况,因为它。对于更加实际的情况(很不如此),您可以查看Dancing Links算法。
答案 1 :(得分:2)
为什么我们说链表插入是恒定时间?
因为 insert 操作是常量时间。
请注意,定位插入位置不被视为 insert 操作本身的一部分。这将是一个不同的操作,可能是也可能不是恒定时间,例如如果包含搜索时间,您将获得:
1)假设你无论如何都在迭代。
相比之下,ArrayList
插入操作是线性时间。如果包含搜索时间,则会获得:
答案 2 :(得分:1)
以下两项操作不同:
操作A:在链接列表中的任何位置插入
操作B:插入链表中的特定位置
操作A可以在O(1)
中实现。如果维护和期望,新元素可以插入head
(或tail
。
操作B涉及查找,然后插入。查找部分为O(n)
。插入如上,即O(1)
。但是,如果将结果作为输入提供,例如,如果存在类似
Node * Find(Node * head, int find_property);
Node * InsertAfter(Node * head, Node * existing_node, Node * new_node);
然后操作的插入部分为O(1)
。