可以快速调整大小的数组

时间:2009-01-05 16:12:30

标签: c# arrays resize performance arraylist

我正在寻找一种可以轻松添加项目的数组数据类型,而不会影响性能。

  • 系统。数组 - Redim Preserve将整个RAM从旧复制到新的,速度与现有元素的数量一样慢
  • System.Collections。 ArrayList - 足够好吗?
  • System.Collections。 IList - 足够好吗?

5 个答案:

答案 0 :(得分:19)

总结一些数据结构:

System.Collections.ArrayList :无类型数据结构已过时。使用List(of t)代替。

System.Collections.Generic.List(of t):这表示可调整大小的数组。此数据结构在后台使用内部数组。只要底层数组尚未填充,向List中添加项目为O(1),否则其O(n + 1)调整内部数组的大小并复制元素。

List<int> nums = new List<int>(3); // creates a resizable array
                                   // which can hold 3 elements

nums.Add(1);
// adds item in O(1). nums.Capacity = 3, nums.Count = 1

nums.Add(2);
// adds item in O(1). nums.Capacity = 3, nums.Count = 3

nums.Add(3);
// adds item in O(1). nums.Capacity = 3, nums.Count = 3

nums.Add(4);
// adds item in O(n). Lists doubles the size of our internal array, so
// nums.Capacity = 6, nums.count = 4

添加项目仅在添加到列表背面时有效。在中间插入会强制数组向前移动所有项目,这是一个O(n)操作。删除项目也是O(n),因为数组需要向后移动项目。

System.Collections.Generic.LinkedList(of t):如果您不需要对列表中的项目进行随机或索引访问,例如您只计划添加项目并从第一次开始迭代为了持续,然后LinkedList是你的朋友。插入和删除是O(1),查找是O(n)。

答案 1 :(得分:16)

您应该使用通用列表&lt;&gt; (System.Collections.Generic.List)为此。它在constant amortized time中运行。

它还与数组共享以下功能。

  • 快速随机访问(您可以访问O(1)中列表中的任何元素)
  • 快速循环
  • 在开头或中间插入和删除对象的速度很慢(因为它必须复制整个列表的内容)

如果您需要在开头或结尾快速插入和删除,请使用链接列表或队列

答案 2 :(得分:3)

LinkedList&lt; T&GT;结构为你工作?它(在某些情况下)不像直线阵列那样直观,但速度非常快。

  • AddLast追加到最后
  • AddBefore / AddAfter以插入列表
  • AddFirst追加到开头

然而,随机访问并不是那么快,因为你必须迭代结构来访问你的项目......但是,它有.ToList()和.ToArray()方法来获取列表中的结构副本/ array form所以对于读访问,你可以在紧要关头做到这一点。插入件的性能增加可能超过随机访问需求的性能降低,或者可能不会。这完全取决于你的情况。

还有这个参考资料可以帮助您确定哪种方法正确:

When to use a linked list over an array/array list?

答案 3 :(得分:1)

什么是“足够好”的?你究竟想用这个数据结构做什么?

没有数组结构(即O(n)访问)允许在没有O(n)运行时的情况下插入中间;最后插入是O(n)最坏的情况,O(1)为自调整大小的数组(如ArrayList)进行摊销。

也许hashtables(在任何地方分摊O(1)访问和插入,但插入的O(n)最坏情况)或树(O(log(n))用于访问和插入任何地方,保证)更适合。

答案 4 :(得分:1)

如果速度是你的问题,我不会看到所选答案如何比使用原始数组更好,虽然它自己调整大小,它使用与调整数组大小完全相同的机制(并且应该只使用更长的触摸)除非你总是添加到最后,在这种情况下,它应该做一些更聪明的事情,因为它一次分配一个块而不是一个元素。

如果您经常在集合的开头/中间附近添加并且不经常索引到中间/结尾,则可能需要链接列表。这将具有最快的插入时间并且将具有很长的迭代时间,它只是在索引时很糟糕(例如从结尾查看第3个元素或第72个元素)。