【问题标题】:Complexity of iteration through std::set通过 std::set 迭代的复杂性
【发布时间】:2015-10-04 03:09:40
【问题描述】:

我知道迭代整个集合的时间复杂度需要O(n) 时间,其中n 是集合的大小。 问题是,在两个迭代器itBeginitEnd 之间进行迭代的复杂度是多少?也许它类似于O(itEnd - itBegin + log n),但我无法证明这一点。

【问题讨论】:

  • 仍然是 O(n),其中 n 是迭代器之间的距离。我建议您重新阅读渐近复杂度的定义。
  • 我认为你错了。例如,如果itEnd = itBegin + 1,那么复杂度将为O(log n),但不是O(1)
  • “例如,如果 itEnd = itBegin + 1,那么复杂度将为 O(log n) 而不是 O(1)” - 你不能推导出 big-O仅从 n=1 的情况来看的复杂性......它是关于当 n 接近无穷大时所需的计算如何变化。
  • n=1 并非如此。 itBegin 不是 s.begin()itEnd 不是 s.end()
  • 好吧...退后一步,“也许它类似于 O(itEnd - itBegin + log n),但我无法证明。” - 不- 就是O(itEnd - itBegin)。如果您知道itEnd - itBegin 平均与n 线性相关,您可以将其简化为 O(n)。 MikeMB 所说的是“O(n),其中 n 是迭代器之间的距离”——即itEnd - itBegin。对于 itEnd = itBegin + 1 的反例 - 在 C++ 中,将 1 添加到迭代器意味着下一个元素:它们相隔 1 并且使用 MikeMB 对 n 的定义作为“迭代器之间的距离”,它确实是 n=1正如我所说的那样。

标签: c++ stl iterator set


【解决方案1】:

复杂度将是 o(n)(n 中的小 o)而不是 O(n),这意味着在最坏的情况下,您将遍历整个集合。

【讨论】:

    【解决方案2】:

    迭代整个std::set 的算法复杂度为 O(n)。但是由于向量使用单个内存块,所以时间消耗比迭代std::vector 要大。

    如果您想在两个迭代器 itBeginitEnd 之间进行迭代,它也将是 O(n1),但 n1 将类似于 std::distance(itEnd, itBegin),在第一种情况下小于 n。当您已经拥有迭代器时就是这种情况。

    如果您想在迭代之前按值查找这些位置(开始时没有迭代器) - 这将变为 O(log n) + O(n2),实际上是 O(log n)。比如说,如果你想从值 123 迭代到末尾 - 这将是 O(log n) 以找到迭代器到 123O(n2) 进行迭代。

    【讨论】:

    • "O(log n) + O(n) 这实际上是O(log n)" - 使用不同的字母来设置大小和距离会更清楚(我将使用 nd),但断言是错误的:说itBeginbegin()itEnd()end() - O(d) 支配 O(log n),而对于附近的itBegin/@ 987654341@ O(log n) 占主导地位:除非有理由认为迭代器将始终接近,否则 O(n) 是更有意义的整体评估。
    • @TonyD 我认为你的断言在这部分是错误的:“说 itBegin 是 begin() 而 itEnd() 是 end() - O(d) 支配 O(log n)”。要得到 begin() 和 end() std::set 不会搜索任何东西,所以它们是 O(1)。然后,它们之间的迭代类似于for(; itBegin!=itEnd; ++itBegin),即 O(n)。所以它的总体 O(n)。
    • 你错过了我说过我会使用 d 来指代集合中迭代器之间的距离......在开始->结束的情况下,d == n,所以 "O(d) 支配 O(log n)" 同意你的分析,它是 O(n)全面的。如果你同意 O(n),更新你的答案怎么样?关于 O(1) 与 O(log n) - 如果您从迭代器开始,您所说的 begin 和 end 都是正确的,但只需按处于或接近这些极端的值搜索一个元素,它会是更一般的 O(log n) 情况。
    • @TonyD 编辑帖子以清除不同大小的n。但是,就算法复杂性而言,我应该提到它在 O(n1) 和 O(n) 之间没有区别,因为它谈论的是复杂性,而不是挂钟时间消耗。
    • “O(n1) 和 O(n) 之间没有区别” - 这取决于正在解决的具体问题是否限制了 n1 更多。例如,如果您有一个任意大的 n,但任务是搜索一个值并在任一侧取多达 100 个值来形成平均值,那么它将由 O(log n) 支配获取迭代器,节点数恒定迭代为 O(1) 并被忽略。总之,我认为正确的答案应该是“成为O(log n)O(n1) 中更糟的那个”,最坏的情况是O(n)。另外,不确定 n2 来自哪里...?
    猜你喜欢
    • 2019-04-30
    • 2012-07-31
    • 1970-01-01
    • 2017-09-09
    • 2014-04-04
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多