std::map
是否在O(1)上查找密钥?我以为是,直到我想得更多。它基于树实现,因此查找时间应该是 O(log N),对吗?
而且,是否有可能让 O(1) 查找字符串键std::unordered_map
?
std::map
是否在O(1)上查找密钥?我以为是,直到我想得更多。它基于树实现,因此查找时间应该是 O(log N),对吗?
而且,是否有可能让 O(1) 查找字符串键std::unordered_map
?
查找的复杂度为std::map
O(log N)(容器大小的对数)。
根据 C++11 标准的第 23.4.4.3/4 段std::map::operator []
:
复杂性:对数。
查找的复杂度std::unordered_map
在平均情况下为 O(1)(常数),在最坏情况下为 O(N)(线性)。
根据 C++11 标准的第 23.5.4.3/4 段std::unordered_map::operator []
复杂性:平均情况 O(1),最坏情况 O(
size()
)。
笔记:
如果您的问题只涉及计算复杂性,那么上面写的应该回答它。实际上,操作的计算复杂度是根据容器的大小(它包含的元素数量)来衡量的。
但是,如果您正在寻找一种在使用字符串键的容器上执行 O(1) 查找的方法,并且查找的复杂性相对于字符串的长度而不是容器的大小是恒定的,那么答案是std::unordered_map
不符合您的要求。
为了查找密钥,首先需要生成它的哈希值;当键是一个字符串时,这个操作本身在字符串的大小上可能是线性的。然后,实现必须将键与同一个桶中的所有字符串键进行比较,并且这些比较中的每一个又与这些字符串的大小呈线性关系。
是的,确实std::map
将具有O(log N)
并且std::unordered_map
将具有平均恒定时间复杂度,并且O(N)
在最坏的情况下,如果有太多的哈希冲突。
基本上 std::map 是使用红黑树实现的。在红黑树中插入和删除操作需要 O(LogN) 时间,因此在 std::map 中,每个元素的时间复杂度为 O(LogN)。
std::unodered_map 是使用散列实现的,其中每个操作都需要 O(1) 时间。