【问题标题】:Complexity of std::set constructor from sorted elements排序元素的 std::set 构造函数的复杂性
【发布时间】:2021-05-22 14:46:04
【问题描述】:

通常,构造rb-treeO(N*log(N)) 时间。

但是,initialization of std::set from sorted elements is linear time

它是如何工作的?初始化前是否有排序检查?还是从最右边开始搜索?

【问题讨论】:

  • 可能出于相同的原因 std::set::insert 重载如果提示实际上是正确的,则需要提示迭代器在恒定时间内工作。只需使用end() 反复调用insert 以获取提示,就可以在线性时间内对已排序的输入起作用。
  • 我试图清理链接,但它似乎破坏了文本突出显示...
  • @FrançoisAndrieux 对我来说,两个版本都没有突出显示。那是 Chrome 的东西吗?
  • @Yksisarvinen 可能是,我正在使用 Chrome。
  • @FrançoisAndrieux 我使用的高光是由铬扩展的Link to text Fragment 制作的。而且你的亮点似乎不适用于我的设备..

标签: c++ algorithm stl


【解决方案1】:

为了将一个元素插入到集合中,集合必须首先确定将其插入的位置。如果它检查的第一个位置是插入它的正确位置,那么该操作的复杂度是 O(1)。如果 每个 插入操作都会发生这种情况,那么所有此类插入的复杂度都是 O(n)。

因此,要实现这一点,该集合只需开始寻找将元素插入的位置,如果序列已排序,插入它。所以如果序列恰好是排序的,搜索时间是O(1),因此插入时间是O(n)。

【讨论】:

  • 需要注意的是复杂度是线性摊销的。该估计不包括在填充树时重新平衡树的复杂性(大概是从一侧)。
  • 但是..如何知道一个序列是否已排序?那么对于任何序列都需要检查吗? (虽然这是一个线性检查..)
  • @zjyhjqs:你不需要。您只需从头到尾进行迭代,依次插入每个元素。而且因为您要跟踪上次插入的位置,如果下一个元素会去那里,那么需要 O(1) 时间才能找到插入它的正确位置。
  • @NicolBolas 如果新元素不是最大的,那么会执行正常的上下搜索吗?
猜你喜欢
  • 2011-01-25
  • 2019-09-23
  • 2015-10-04
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 1970-01-01
相关资源
最近更新 更多