散列表和映射是散列表实现为散列函数,但映射是作为树实现的。
我的问题是,在什么情况下,哈希表不能用,但地图是必须的?
答案 0 :(得分:5)
有许多潜在的原因。
std::map
指定的排序是必要或可取的时候。答案 1 :(得分:2)
选择在哈希表上使用映射的一个动机是每个对模板实例化中使用的键类型的约束。如the documentation for hash_map in the SGI implementation of STL中所述,实例化hash_map需要提供散列K的仿函数.STL包含一个仿函数std::hash,它执行此操作,但它仅针对有限的一组类型T实现。
另一方面,std :: map的实例化只需要一个比较K类对象的仿函数来生成弱排序。标准仿函数std::less适用于定义运算符<。
的任何T这意味着,对于许多用户定义的类型,添加将类型用作std :: map中的键所需的支持远小于在std :: hash_map中使用它所需的支持。
除了开销问题外,
答案 2 :(得分:2)
运行时特征是不同的:
基于树的地图始终具有O(log n )的运行时(最差情况,平均情况),即(平衡的)高度)二叉搜索树。
另一方面,哈希映射具有更复杂的运行时行为。但在通常情况下,哈希表的预期运行时为O(1),即常量开销。
一般来说,最坏情况是O( n ),这听起来很糟糕。然而,可以证明,对于良好的参数选择,这种最坏的情况变得非常罕见,以至于在实践中不起作用。 “罕见”在这里意味着真的罕见,如连续十次赢得彩票然后被彗星杀死。实际上,参数的错误选择(散列技术,载荷因子......)可以大大提高这种可能性。
答案 3 :(得分:1)
当您依赖于键的排序时。
答案 4 :(得分:1)
我将回答关于std :: unordered_map(哈希表)和std :: map(树)的问题。请注意,这些都没有实际指定实现机制。基本上,当您需要按排序顺序访问键时使用map,否则使用unordered_map。
答案 5 :(得分:1)
如果您需要在数据结构中找到“下一个”项,则无法使用哈希表,因为它不会以可遍历的顺序保留项目。