用Java的语境说话。如果我想在ArrayList
或linkedList
的中间插入,我会被告知Arraylist
会表现得非常糟糕。
据我所知,这是因为我们需要移动所有元素,然后进行插入。这应该是n / 2的顺序,即O(n)。
但linkedList
不一样。对于链接List,我们需要遍历直到找到中间的时间,然后执行指针操作。在这种情况下,也需要O(n)时间。不是吗?
由于
答案 0 :(得分:6)
这里的原因是链表中没有实际的转移元素。链接列表是从节点构建的,每个节点都包含一个元素和一个指向下一个节点的指针。要将元素插入列表只需要几件事:
如果您曾制作过一系列纸夹,您可以将每个纸夹视为其链条的开始以及之后的所有纸夹。要将新的回形针固定到链条中,您只需要在新的回形针的位置断开回形针,然后插入新回形针。 LinkedList
就像一个回形针链。
ArrayList
有点像pillbox或mancala board,其中每个区域只能容纳一个项目。如果你想在中间插入一个新元素(并保持所有元素的顺序相同),你将不得不在那个位置后移动所有。
链接列表中给定节点之后的插入是常量时间,只要您已经有对该节点的引用(在Java中使用ListIterator
),并且到达该位置通常需要在节点的位置线性时间。也就是说,要到达_n_th节点需要 n 步骤。在数组列表(或数组,或任何基于连续内存的结构中,实际上),列表中_n_th元素的地址只是(第一个元素的地址)+ n×(元素的大小),一个微不足道的算术,我们的压缩设备支持快速访问任意内存地址。
答案 1 :(得分:0)
我认为,在分析复杂性时,您需要考虑您正在使用的指标。在ArrayList
中,您的指标为shuffling
,这只是作业。但这是一项非常复杂的操作。
另一方面,你正在使用LinkedList
,而你只是想看看参考。实际上,您只执行1次插入。因此,虽然算法复杂度最终会相似,但O(n)
时执行的实际流程却不同。在ArrayList
的情况下,它正在执行大量的内存操作。在LinkedList
的情况下,它只是阅读。
对于那些说他不懂LinkedLists的人
LinkedList只有一个指向开头,一个指针在结尾。它不会自动知道要删除的节点后面的Node (除非它是一个双向链表),所以你需要遍历列表,从一开始就创建一个临时指针,直到你来到你要删除的节点之前的节点,我相信OP正在讨论这个。