【问题标题】:O(1) lookup in C++C++ 中的 O(1) 查找
【发布时间】:2012-05-15 11:15:12
【问题描述】:

C++ 中是否有带有O(1) 查找的数据结构?

std::map 具有 O(log(n)) 查找时间(对吗?)。

我最好从std 中寻找东西(所以不是Boost pls)。另外,如果有,它是如何工作的?

编辑:好的,我猜我还不够清楚。我想关联值,有点像map。所以我想要std::map<int,string>findinsert 应该采用O(1)

【问题讨论】:

  • 这完全取决于数据,尤其是key的类型和可能值:那么你要存储什么样的数据呢?
  • 可能类似于链接数组的东西?它大约有 O(1)。链接数组是数组的链接列表。
  • std::unordered_map<>。它之所以在命名空间std 中,是因为它首先在命名空间boost 中。
  • std::unordered_map,在C++11之前是std::tr1::unordered_map
  • @DeadMG:如果他需要std::map 之类的东西,那么他需要std::map,除非他告诉我们std::map 为他提供了更多 比他实际上需要。

标签: c++ data-structures stl std


【解决方案1】:

数组有 O(1) 的查找。 c++11 的哈希表 (std::unordered_map) 具有 O(1) 查找。 (摊销,但或多或​​少保持不变。)

我还想提一下,基于树的数据结构(如地图)具有很大的优势,并且只有 log(n),这往往是不够的。

回答您的编辑 -> 您可以从字面上将数组的索引与其中一个值相关联。哈希表也是关联的,但完美的哈希(每个键都映射到恰好 1 个值)确实很难获得。

还有一点值得一提:数组具有出色的缓存性能(由于局部性,也就是元素彼此相邻,因此它们可以被 prefecting 引擎预取到缓存中)。树,不多。在元素数量合理的情况下,哈希性能可能比渐近性能更为关键。

【讨论】:

  • 另外值得一提的是TR1中有一个无序映射。 VS2008 和更早的 GCC 等一些编译器实现了 TR1,但没有实现 C++11。
  • @scarletamaranth 数组如此高效的主要原因是因为它们彼此相邻 -> 系统只是按照您所说的方式在内存中跳转(索引结束 + sizeof(type)*index)你说的缓存不是很清楚。
  • @ScarletAmaranth 是的,但缓存可能会被误解。我希望你在一些来自 web 开发的人仇恨之前多解释一下
  • @Shingetsu “由于局部性,也就是元素彼此相邻,因此可以预取”应该足够清楚;)
  • @ScarletAmaranth 我猜,它仍然有助于让人们了解预取引擎的工作原理。但是我现在就不打扰了,不能让每个人都选择性地成为完美主义者XD
【解决方案2】:

O(1) 查找的数据结构(忽略键的大小)包括:

  • 数组
  • 哈希表

对于复杂类型,平衡树在 O(log n) 时会很好,或者有时您可以在 O(k) 时使用patricia trie

供参考:complexity of search structures

【讨论】:

  • 数组不是关联的。 std 中有什么哈希表?
  • @AMCoder:有std::unordered_map
  • 哈希表不是 O(1) - 仍然必须进行冲突处理检查,并在发生冲突时迭代存储桶。最好的情况是 O(1),但并非总是如此。
  • @MarcB:它们的摊销时间为 O(1)。
  • O(1 + k/n) 对我来说已经足够接近了。
【解决方案3】:

array 具有 O(1) 查找。

【讨论】:

  • 我认为 OP 事先并不知道尺寸
  • 如果密钥不完整怎么办?那时简单的数组就行不通了。所以这取决于键的数据类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
相关资源
最近更新 更多