C++中std::map
的插入、删除和查找时间复杂度是否为O(log n)
?是否可能实现O(1)
的哈希表?
std:map
相对于std:unordered_map
有什么优势呢? - Paul S.std::map
使用树结构,需要对键进行比较,而std::unordered_map
要求键可以被哈希。此外,我不能假设std::unordered_map
总是更快,尤其是对于小数据(但如果您认为这很重要,请自行检查)。 - Kosunordered_map
也需要其键可比较; 它只是与 map
(less
) 不同的默认比较器 (equal_to
)。 - PraetorianC++有一个unordered_map
类型。STL还包含一个hash_map
类型,尽管这不在C++标准库中。
现在,让我们来谈一下算法理论。在完美情况下,可以实现O(1)哈希表,技术上,哈希表是O(1)的插入和查找。在这种情况下,完美条件是哈希函数必须是完美的(即无冲突),并且您拥有无限的存储空间。
在实践中,我们采用一个愚蠢的哈希表。对于任何输入键,它返回1。在这种情况下,当发生冲突(即第二次及以后的插入)时,它将不得不进一步链接以找到一些空闲空间。它可以转到下一个存储位置,或者使用链表。
无论如何,在最好的情况下,哈希表是O(1)的(当然,一旦你耗尽了所有的哈希值,这是不切实际的,因为没有无限输出的哈希函数)。在最坏的情况下(例如,使用我完全愚蠢的哈希函数),哈希表是O(n)的,因为您将不得不遍历存储以找到给定哈希的实际值,因为初始值不是正确的值。
hash_map
是大多数编译器提供的非标准扩展。标准哈希映射被称为unordered_map
。 - Praetorianstd::map
的实现是一棵树。虽然标准没有直接规定,但一些好的书籍说过:"很难想象它会是其他什么东西"
。这意味着 map 的插入/删除/查找时间为 O(log n)。
经典哈希表的查找时间为 O(n/num_slots)。一旦表中预期的项目数与插槽数量相当,您将拥有 饱和
的 O(1)。
std::unordered_map
,如果您有boost,则可以使用boost::unordered_map
。 - andrestd::map
是一个哈希表,但它们通常是二叉树。 - Brendan Longmap
/unordered_map
),但它们内部的实现完全不同。 - Brendan Long