.NET集合类的渐近复杂性

时间:2009-05-12 09:31:26

标签: .net collections big-o asymptotic-complexity

有没有关于.NET集合类(Dictionary<K,V>List<T>等方法的渐近复杂性(big-O和其余)的资源?)

我知道C5库的文档包含了一些关于它的信息(example),但我也对标准的.NET集合感兴趣...(而且PowerCollections的信息也很好)。

6 个答案:

答案 0 :(得分:25)

MSDN列出这些:

等。例如:

  

SortedList(TKey,TValue)泛型   class是二叉搜索树   O(log n)检索,其中n是   字典中的元素数量。   在这,它类似于   SortedDictionary(TKey,TValue)泛型   类。这两个类有相似之处   对象模型,都有O(log n)   恢复。哪两个班   不同的是内存使用和速度   插入和移除:

     

SortedList(TKey,TValue)使用更少   内存比SortedDictionary(TKey,   TValue)。

     

SortedDictionary(TKey,TValue)有   更快插入和移除   未排序数据的操作,O(log n)   而不是O(n)   SortedList(TKey,TValue)。

     

如果列表一次全部填充   来自排序数据,SortedList(TKey,   TValue比快   SortedDictionary(TKey,TValue)。

答案 1 :(得分:21)

This page总结了使用Java的各种集合类型的一些复杂性,尽管它们对于.NET应该完全相同。

我从该页面获取了表格,并为.NET框架更改/扩展了它们。 另请参阅SortedDictionarySortedList的MSDN页面,其中详细说明了各种操作所需的时间复杂性。


搜索

Type of Search/Collection Types           Complexity  Comments
Linear search Array/ArrayList/LinkedList  O(N)        Unsorted data.
Binary search sorted Array/ArrayList/     O(log N)    Requires sorted data.
Search Hashtable/Dictionary<T>            O(1)        Uses hash function.
Binary search SortedDictionary/SortedKey  O(log N)    Sorting is automated.

检索和插入

Operation         Array/ArrayList  LinkedList  SortedDictionary  SortedList
Access back       O(1)             O(1)        O(log N)          O(log N)
Access front      O(1)             O(1)        N.A.              N.A.
Access middle     O(1)             O(N)        N.A.              N.A.
Insert at back    O(1)             O(1)        O(log N)          O(N)
Insert at front   O(N)             O(1)        N.A.              N.A.
Insert in middle  O(N)             O(1)        N.A.              N.A.

删除应该与关联集合的插入具有相同的复杂性。

SortedList有一些值得注意的插入和检索特性。

插入(添加方法):

  

此方法是O(n)操作   未排序的数据,其中n是Count。它是   如果是新的O(log n)操作   元素添加在结尾处   名单。如果插入导致调整大小,   操作是O(n)。

检索(项目属性):

  

检索此属性的值   是一个O(log n)操作,其中n是   计数。设置属性是一个   如果键是O(log n)操作   已经在SortedList&lt;(Of&lt;(TKey,   TValue&GT;)&GT)。如果钥匙不在   列表,设置属性是O(n)   未排序数据的操作,或O(日志   n)如果新元素添加在   列表的末尾。如果插入导致   调整大小,操作是O(n)。

请注意,就所有操作的复杂性而言,ArrayList相当于List<T>


答案 2 :(得分:2)

我一般都不知道(刚发布的另一个答案可能会给你提供你正在追求的内容) - 但你可以使用ILSpy来反映这个和其他方法(FSharp代码有点尴尬,真实)这最终会产生这个函数为C#:

internal static a maximumElementAux<a>(SetTree<a> s, a n)
{
  while (true)
  {
    SetTree<a> setTree = s;
    if (setTree is SetTree<a>.SetOne)
    {
      break;
    }
    if (setTree == null)
    {
      return n;
    }
    SetTree<a>.SetNode setNode = (SetTree<a>.SetNode)s;
    SetTree<a> arg_23_0 = setNode.item3;
    n = setNode.item1;
    s = arg_23_0;
  }
  return ((SetTree<a>.SetOne)s).item;
  return n;
}

好的,所以这不是C#术语中的“正确”代码 - 但while(true)循环的存在意味着它至少不能是O(1);至于实际上是什么......好吧,我的头痛得太多了,无法找到:)

答案 3 :(得分:2)

此页面提供了一些关键专业人士的简短说明。大多数.NET集合的缺点:

http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx

答案 4 :(得分:0)

没有“收集类的复杂性”这样的东西。相反,对这些集合的不同操作具有不同的复杂性。例如,向Dictionary<K, V> ...

添加元素
  

...接近 O(1)操作。如果必须增加容量以容纳新元素,则此方法将成为 O(n)操作,其中nCount

Dictionary<K, V> ...

中检索元素
  

...接近O(1)操作。

答案 5 :(得分:0)

文档说它是在二叉树上构建的,并没有提到跟踪最大元素。如果文档是正确的,那意味着它应该是O(log n)。集合文档中曾经存在至少一个错误(将数组支持的数据结构称为二叉搜索树),但这已经得到纠正。