有没有关于.NET集合类(Dictionary<K,V>
, List<T>
等等) 方法渐近复杂度 (大O表示法等) 的相关资源?
我知道C5库的文档包括一些相关信息(例子),但我也对标准.NET集合类感兴趣...(还有 PowerCollections 的信息也不错)。
有没有关于.NET集合类(Dictionary<K,V>
, List<T>
等等) 方法渐近复杂度 (大O表示法等) 的相关资源?
我知道C5库的文档包括一些相关信息(例子),但我也对标准.NET集合类感兴趣...(还有 PowerCollections 的信息也不错)。
MSDN列出了以下内容:
Dictionary<,>
List<>
SortedList<,>
(编辑:错误的链接;这是通用版本)SortedDictionary<,>
等等。例如:
SortedList(TKey, TValue)泛型类是一个带有O(log n)检索的二叉搜索树,其中n是字典中元素的数量。在这方面,它与SortedDictionary(TKey, TValue)泛型类相似。两个类具有类似的对象模型,并且都具有O(log n)检索。两个类之间的区别在于内存使用和插入和删除速度:
SortedList(TKey, TValue)使用的内存比SortedDictionary(TKey, TValue)少。
对于未排序的数据,SortedDictionary(TKey, TValue)具有更快的插入和删除操作,O(log n),而SortedList(TKey, TValue)为O(n)。
如果列表一次性从排序数据中填充,则SortedList(TKey, TValue)比SortedDictionary(TKey, TValue)更快。
本页面总结了Java中各种集合类型的一些时间复杂度,尽管它们对于.NET应该完全相同。
我从那个页面上获取了表格,并为.NET框架进行了修改/扩展。 另请参阅MSDN页面SortedDictionary和SortedList,其中详细说明了各种操作所需的时间复杂度。
搜索类型/集合类型 复杂度 说明 线性搜索 数组/ArrayList/LinkedList O(N) 未排序的数据。 二分搜索 已排序的数组/ArrayList/ O(log N) 需要排序的数据。 搜索 Hashtable/Dictionary<T> O(1) 使用哈希函数。 二分搜索 SortedDictionary/SortedKey O(log N) 自动排序。
操作 数组/ArrayList LinkedList SortedDictionary SortedList 访问末尾 O(1) O(1) O(log N) O(log N) 访问开头 O(1) O(1) N.A. N.A. 访问中间 O(1) O(N) N.A. N.A. 在末尾插入 O(1) O(1) O(log N) O(N) 在开头插入 O(N) O(1) N.A. N.A. 在中间插入 O(N) O(1) N.A. N.A.
删除应与相应集合的插入具有相同的复杂度。
SortedList在插入和检索方面有一些值得注意的特殊情况。
插入(Add方法):
对于未排序的数据,此方法是一个O(n)操作,其中n是Count。如果新元素添加到列表末尾,则它是一个O(log n)操作。如果插入导致调整大小,则操作为O(n)。
检索(Item属性):
检索该属性的值是 O(log n) 操作,其中 n 是 Count。如果键已经在 SortedList<(Of <(TKey, TValue)>)> 中,设置属性是 O(log n) 操作。如果键不在列表中,则对于未排序的数据,设置该属性是 O(n) 操作,或者如果新元素添加到列表末尾,则是 O(log n) 操作。如果插入导致调整大小,则操作为 O(n)。请注意,所有操作的复杂度方面,ArrayList 等效于 List。我不确定一般情况下是怎样的(也许其他答案已经给出了你需要的答案)- 但是你当然可以使用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); 至于它到底是什么... 好吧,我的头疼得太厉害了,无法找出答案 :)