使用std :: set的std :: lower_bound的时间复杂度是多少?

时间:2013-08-11 09:28:04

标签: c++ algorithm stl set complexity-theory

我知道有std::set::lower_bound且时间复杂度为O(log),我发现std::lower_boundstd::set::lower_bound上运行时比std::set慢得多std::advance

我用Google搜索并发现了这个:

http://en.cppreference.com/w/cpp/algorithm/lower_bound http://en.cppreference.com/w/cpp/iterator/advance

所以很清楚,因为set::iterator的{​​{1}}是线性的,所以整个std::lower_bound最多只占O(n)

然而,当我使用它时,它的运行速度比O(n)快得多(有些朋友也这么说),任何人都可以解释原因或告诉我它不是那样的。

2 个答案:

答案 0 :(得分:1)

std::lower_bound()的保证复杂性在非随机访问迭代器上为O(n)。如果该算法检测到搜索在有序关联容器上,则可以利用树结构可能实现更好的复杂性。是否有任何实现,我不知道。

答案 1 :(得分:1)

TL; DR:每当容器提供与现有算法同名的方法时,它就会这样做,因为内部实现更快(依赖于容器的属性),因此你应该只是用它。


问题在于复杂性是变幻无常的:O(N)什么

非随机访问迭代器的复杂性保证是:

  • O(N)次迭代
  • O(log2(N))比较

根据迭代或比较是否是瓶颈,这实际上改变了一切!

理论上,对于已排序的关联容器,人们可能希望专门化std::lower_bound以利用数据已经排序的事实;但实际上这是相对困难的。主要问题是没有人知道set的比较谓词和传递给lower_bound的比较谓词确实是同一个,因此算法需要假定情况并非如此(除非经过验证)除此以外)。并且因为该算法采用迭代器而不是范围/容器,否则将留作读者的练习