我正在尝试在std::map
中找到最大值,该值将是树中的最后一个节点(因为对std::map
键进行了排序)。
Cppref说std::map.end()
是恒定时间。但是要获得最大的密钥,我必须获得此迭代器的先前值,即*std::prev(std::map.end())
。
该操作的时间复杂度是多少?
我知道这应该等于--std::map.end()
,但我也不知道该操作的成本。
答案 0 :(得分:7)
返回指向容器中最后一个元素的反向迭代器(即其反向开始)。
和:
复杂度
恒定。
最后一个单词在您耳边听起来像是音乐。
std::prev(std::map.end())
的复杂度为constant。
此外,您对等效性的理解是错误的。
摘自std::prev
注释:
尽管表达式
--c.end()
经常编译,但它不是 确保这样做:c.end()
是一个右值表达式,并且有 没有迭代器要求指定右值的递减为 保证工作。特别是,当迭代器实现为 指针,--c.end()
不会编译,而std::prev(c.end())
会。
答案 1 :(得分:5)
Advancing in any direction is linear in the number of advances(在您的情况下为 ,因此我们可以将其称为固定时间),但是您无需这样做。只需使用rbegin()
,它是最后一个元素的迭代器。
std::prev
与--std::map.end()
不等效,后者根本不能保证做任何有用的事情。请参阅std::prev
文档。
答案 2 :(得分:3)
但是要获得最大的密钥,我必须获取此迭代器的先前值,即
*std::prev(std::map.end())
。该操作的时间复杂度是多少?
std::map.end
,std::prev(a_std_map_iterator)
和std::map::iterator::operator*
中的所有都是恒定操作。因此,该表达式在整体上是恒定的。
请注意,根据第二个参数std::prev
(默认为1),保证n
的复杂度最多为线性。当n
为常数时,{{1 }}总体上是恒定的。