我正在寻找一种可以轻松添加项目的数组数据类型,而不会影响性能。
Redim Preserve
将整个RAM从旧复制到新的,速度与现有元素的数量一样慢答案 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中运行。
它还与数组共享以下功能。
如果您需要在开头或结尾快速插入和删除,请使用链接列表或队列
答案 2 :(得分:3)
LinkedList&lt; T&GT;结构为你工作?它(在某些情况下)不像直线阵列那样直观,但速度非常快。
然而,随机访问并不是那么快,因为你必须迭代结构来访问你的项目......但是,它有.ToList()和.ToArray()方法来获取列表中的结构副本/ array form所以对于读访问,你可以在紧要关头做到这一点。插入件的性能增加可能超过随机访问需求的性能降低,或者可能不会。这完全取决于你的情况。
还有这个参考资料可以帮助您确定哪种方法正确:
答案 3 :(得分:1)
什么是“足够好”的?你究竟想用这个数据结构做什么?
没有数组结构(即O(n)访问)允许在没有O(n)运行时的情况下插入中间;最后插入是O(n)最坏的情况,O(1)为自调整大小的数组(如ArrayList)进行摊销。
也许hashtables(在任何地方分摊O(1)访问和插入,但插入的O(n)最坏情况)或树(O(log(n))用于访问和插入任何地方,保证)更适合。
答案 4 :(得分:1)
如果速度是你的问题,我不会看到所选答案如何比使用原始数组更好,虽然它自己调整大小,它使用与调整数组大小完全相同的机制(并且应该只使用更长的触摸)除非你总是添加到最后,在这种情况下,它应该做一些更聪明的事情,因为它一次分配一个块而不是一个元素。
如果您经常在集合的开头/中间附近添加并且不经常索引到中间/结尾,则可能需要链接列表。这将具有最快的插入时间并且将具有很长的迭代时间,它只是在索引时很糟糕(例如从结尾查看第3个元素或第72个元素)。