List<T>和LinkedList<T>的区别

45

每当我们需要列表时,我们使用List。我现在注意到有一个LinkedList。

我想知道这两者之间的区别,以及何时该使用其中之一。

3个回答

100

嗯,List<T> 基本上由一个通常比当前项目数量大的数组支持。元素被放入数组中,并在旧数组耗尽空间时创建一个新数组。这对于索引访问很快,但在列表内删除或插入元素或在开头进行操作时很慢。在列表末尾添加/删除条目相对便宜。

LinkedList<T> 是一个双向链接列表 - 每个节点都知道其前一个条目和下一个条目。这对于在特定节点(或头部/尾部)之后/之前插入很快,但按索引访问很慢。

LinkedList<T> 通常会占用比 List<T> 更多的内存,因为它需要为所有这些 next/previous 引用提供空间 - 并且数据可能具有更少的引用局部性,因为每个节点是单独的对象。另一方面,List<T> 可以具有远大于其当前需求的支持数组。


LinkedList<T>是否比List<T>能够容纳更多的值? - Shrivallabh
@Shrivallabh:你所说的“容纳更多值”是什么意思?这将取决于上下文、您使用的CLR版本等因素。除非您计划存储大量元素,否则这很不可能有关。 - Jon Skeet
我有一个应用程序,需要读取大型文本文件,并且需要存储每行中的ID,因此询问LinkedList<T>是否更好还是List<T>。 - Shrivallabh
@Shrivallabh: "巨大"是多大?有多少行代码?请记住,如果您事先知道最终条目数量,List<T>在内存使用方面可能更加高效 - Jon Skeet
我不知道数量,文件大约在20到40 GB左右,每行都有ID。 - Shrivallabh

12

List<T>是实际上是一个数组,这意味着在结尾处进行Add操作的时间复杂度为O(1),而在开头则为O(n),但你可以用O(1)的时间复杂度对其进行索引。而LinkedList<T>正如其名,是一个链表。由于它是双向链表,因此您可以在O(1)的时间内在前面或后面添加项目,但是对其进行索引的时间复杂度为O(n)。


4
不确定你从哪里得到 Add 的时间复杂度是 O(log n) - 我会预期它是摊销常数时间。 - Jon Skeet
Jon:你可能是对的。我想我试图在O(1)结尾和O(n)开头之间做一些平均。 - Gabe

2

在几乎所有情况下,List都会比LinkedList表现更优。但在实际应用中,结果有时与大O复杂度理论不同。

原始答案:Original Answer


为什么这个被踩了?它是真的。看看这篇帖子 https://dev59.com/yXVC5IYBdhLWcg3w1E1q。我在不同的网站上找到了许多其他人得到与此帖子相同的结果。实际上,几乎没有一种情况下链表比通用列表更好。 - MattE
这应该是一条注释,而不是答案。您没有回答问题的重要部分,也没有解释这两种类型的区别。此外,您没有解释为什么和何时一种比另一种更好。这就是人们将您的投票降低的原因。 - Antonio Rodríguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接