std::map 迭代器和插入的行为

Behavior of std::map iterators and insertions

作为一个简单的开始

Map<key,val> map1=//filled up in some way;
Map<key,val> map2;
map2.insert(map1.begin(),map1.end());

我们知道 map::insert 是 O(log(n)),没有提供提示。这是否意味着上面的 运行s 在 O(nlog(n)) 中,或者它是否使用了 map1 已经排序并简单地插入到正确位置(递增当前迭代器)的事实?因为 map1 已经排序,所以我们应该能够在线性时间内完成此操作。怎么样

std::copy(map1.begin(),map1.end(),map2.end());

它是每次都在 O(log(n)) 中插入,还是在 O(1) 中复制到通过递增迭代器标记的受尊重的位置?

也许是一个更能说明问题的例子

template<class InIter, class OutIter, class ResIter>
ResIter foo(InIter first, OutIter last, ResIter res){
   while(first!=last){
      res=*first;
      ++first;
      ++res;
   }
return res;
}

当我们处理映射迭代器时,这个 运行 是 O(n) 还是 O(nlog(n))?插入是 O(log(n)),还是 O(1),因为我们指定了位置,即 *res=*first?

为清楚起见编辑:

*res=*first

表现得像

map2.insert(res,*first)

意思是,插入到 map2 中,使用指向正确位置的迭代器 res 作为提示,使其成为 O(1),还是执行常规的 O(log(n)) 插入?

快速阅读标准后,对void insert(InputIterator first, InputIterator last);的复杂性没有要求。因此,允许惰性实现具有 O(n log(n)) 复杂性,即使由于以下原因 map1 为空,它也可能是线性的。

因为如果输入范围已排序,标准确实要求构造函数的线性复杂度,所以这需要为 O(n):

Map<key,val> map1=//filled up in some way;
Map<key,val> map2(map1.begin(),map1.end()); // complexity in O(n)

对于你问题的第二部分,因为你想给出元素插入位置的提示,正确的方法是:

template<class InIter, class OutIter, class ResIter>
ResIter foo(InIter first, OutIter last, ResIter res){
   while(first!=last){
      emplace_hint(res, *first);
      ++first;
      ++res;
   }
return res;
}

不幸的是,标准对 emplaceemplace_hint.

的复杂性没有要求