【问题标题】:Is there any thing hashmap can do but map cannot?有什么 hashmap 可以做但 map 不能做的事情吗?
【发布时间】:2011-02-02 06:47:15
【问题描述】:

我只知道hashmap和map的区别是hashmap是用hash函数实现的,而map是用tree实现的。任何机构都可以添加更多内容吗?

基于此,有没有什么hashmap能做而map不能做的事情?

【问题讨论】:

  • 有点类似,但也许不是骗子:stackoverflow.com/questions/2196995/…
  • 对术语要小心一点。在某些圈子中,“映射”仅指进行键/值存储和查找的对象,而“哈希映射”是映射的一种实现。 (树图可能是另一个。)。 IOW,“map”是一个接口,“hash map”是一个具体的实现。 (我注意到这一点是因为您的问题没有被标记为或引用任何特定的库。)
  • @Ben:在 C++ 中,map 几乎毫不含糊地指代std::map,一棵树。

标签: c++ data-structures map hashmap unordered-map


【解决方案1】:

hashmap 优于树的一个优点是,在多线程环境中,您不必锁定整个容器来添加或删除单个键 - 锁定哈希表中的单个相关条目(几乎) 够了。

几乎是因为可能需要更新元数据(例如哈希表中的项目数)。当然,您可能需要锁定整个表以扩大或缩小它。

【讨论】:

    【解决方案2】:

    映射要求键具有严格的弱排序,这可能不存在。哈希图只需要一个哈希函数。因此,通过这种方式,hashmap 可以与没有严格弱排序的键一起使用。

    【讨论】:

    • 老实说,树和哈希图在这里有同样的问题。这是我最近不得不使用有限自动机作为键来解决的一个问题。您不能只对内存中的表示进行散列(或比较),因为等效的自动机可以有不同的表示。解决方案是导出规范形式。一旦你有了一个规范的形式,你就可以从内存中的表示中很好地工作,无论你是比较还是散列——这几乎适用于任何类型的数据。如果可以散列,则可以轻松定义任意但一致的顺序。
    【解决方案3】:
    • Hashmaps 在平均情况下的访问性能更好 (O(1)),但在最坏情况下的性能更差 (O(n))。地图总是 O(lg(n))。

    • 映射按其键排序,哈希映射不是。

    • Hashmaps 通常比 Maps 使用更多的内存。

    • 映射通常允许更快的迭代。

    • 良好的哈希函数比良好的排序函数更难编写(也更难分析)。

    我不相信 hashmap 可以做任何 map 做不到的事情。

    【讨论】:

    • 哈希图通常也使用更多内存。
    • IMO 对哈希表的 O(1) 声明有点作弊。在没有碰撞处理的情况下识别为不同的键的数量有一个固定的界限,一旦发生碰撞,性能就会下降到碰撞处理的性能(通常为 O(n))。好的,哈希传统上支持尽可能多的唯一键,因为您可以存储在内存中 - 但我想知道有多少人忽略了将自定义哈希计算从 32 位升级到 64 位,并且会因非常大的哈希表而降低性能。如果哈希本身太窄,没有大小哈希表可以解决这个问题。
    • @Steve - 我提到 O(1) 是平均情况,O(n) 是最坏情况。 @GMan - 谢谢,我会补充的。
    • @Poita - 是的,但我的评论涉及一种特定且经常被忽略的方式,在这种方式中,理论上的 O(n) 最坏情况可以成为现实世界的事实。即使我们使用 512 位机器,如果发生这种情况,您现有的 std::map 代码也可以正常工作 - 但旧的基于 hashmap 的代码很可能需要(又一次)重新设计以有效地利用未来时间的巨大记忆。
    • @GMan:澄清一​​下,hashmap 是如何比 map 使用更多的内存的?这是否仅在某些情况下(例如少数元素)或始终发生? Map 被实现为一棵树,它导致额外的指针。
    猜你喜欢
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多