当操作“接近O(1)”而不是“是O(1)”时,它意味着什么?

时间:2013-11-14 21:46:33

标签: c# .net optimization big-o

例如,考虑.NET Framework 4.5 Dictionary<TKey, TValue>类的文档:

.ContainsKey方法的remarks中,他们说明了

  

此方法接近O(1)操作。

.Count属性的remarks中,他们说明了

  

检索此属性的值是O(1)操作。

请注意,我不是必然要求提供C#.NETDictionary的详细信息或一般的Big O符号。我刚刚发现这种“方法”的区别很有趣。

有什么区别吗?如果是这样,它可能有多重要?我应该注意它吗?

4 个答案:

答案 0 :(得分:10)

如果哈希码中底层对象使用的哈希函数“好”,则意味着冲突将非常罕见。可能性很大,在给定的哈希桶中只有一个项目,可能是两个,几乎从不多。如果您可以肯定地说,在一个存储桶中永远不会有超过c项(其中c是常量),那么操作将是O(c)(即O( 1))。但这种保证是无法做到的。它是可能,你碰巧有n个不同的项目,不幸的是,所有项目都发生碰撞,并且最终都在同一个桶中,在这种情况下,ContainsKey是O(n )。哈希函数也可能不是“好”并且经常导致哈希冲突,这可能使实际包含检查比仅仅O(1)更糟。

答案 1 :(得分:4)

这是因为Dictionary是hash tables的实现 - 这意味着通过使用散列函数完成键查找,该函数告诉您数据结构中包含的多个存储桶中的哪个存储桶包含您正在查找的值。通常,对于良好的散列函数,假设一组足够大的桶,每个桶只包含一个元素 - 在这种情况下,复杂性确实是O(1) - 不幸的是,这并不总是正确的 - 散列函数可能有冲突在这种情况下,一个存储桶可能包含多个条目,因此算法必须遍历存储桶,直到它找到您正在查找的条目 - 因此对于这些(希望)罕见的情况,它不再是O(1)。 / p>

答案 2 :(得分:0)

O(1)是一个恒定的运行时间,接近O(1)接近常数但不完全,但对于大多数目的而言,增加可忽略不计。你不应该注意它。

答案 3 :(得分:0)

某些东西是否是O(1)。我认为他们试图说的是,对于大量操作,每次操作的运行时间大约是O(1)。