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

时间:2017-03-31 09:43:22

标签: c++ iterator time-complexity stdmap

作为一个简单的开始

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

我们知道map::insert是O(log(n)),没有提供提示。这是否意味着上面的内容在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))插入?

1 个答案:

答案 0 :(得分:1)

快速阅读标准后,对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的复杂性没有要求。