deque :: insert()在索引?

时间:2011-10-22 20:24:11

标签: c++ deque

如何在线性时间insert()deque个项目{{1}}放在{{1}}的中间位置?

(我插入的项目可通过STL样式的迭代器访问。)

4 个答案:

答案 0 :(得分:6)

有一个deque::insert(iterator pos, const T&x)函数将位置pos作为deque::iterator和一个元素。使用此方法,您可以逐个插入所有元素。 pos可以很容易地获得deque.begin()+index(如果您有一个索引,在此之前要插入元素)。 insert方法返回新插入元素的迭代器,只需递增此返回的迭代器即可获得下一个位置:

deque::iterator it = myDeque.begin()+index;
while(n--) {
  it = myDeque.insert(it, currentElement);
  it++;
  currentElement = ... // However you get your next element ...
}

然而这可以是O(n*k)时间,因为插入单个元素是(iirc)线性时间操作iirc。

第二个重载是deque::insert(iterator pos, InputIterator f, InputIterator l):请记住,简单的指针也满足STL输入迭代器的要求,所以如果你有一个长度为T array[]的C样式数组n包含你的元素,您可以使用

插入此数组中的所有元素
d.insert(pos, array, array+n);

该操作可以在线性时间内进行,即O(n+k)。我不确定这是否由标准保证,但我想大多数实现都会有效地完成。

编辑

我很快检查了微软的实现,他们按照push_backpush_front的顺序进行检查,无论接近pos,然后将元素旋转到最终位置,保证上述O(n+k)复杂性。当然,这也可以“手工”完成,如:

size_type _Off = pos - d.begin();
size_type _Oldsize = d.size();
if (_Off <= d.size() / 2)
{   // closer to front, push to front then rotate
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  size_type _Num = d.size() - _Oldsize;
  std::reverse(d.begin(), d.begin() + _Num); // flip new stuff in place
  std::rotate(d.begin(), d.begin() + _Num, begin() + _Num + _Off);
}
else
{ // closer to back
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  std::rotate(begin() + _Off, begin() + _Oldsize, end());
}

(我复制了deque::insert的Microsofts实现中的代码,删除了调试代码和异常处理,

答案 1 :(得分:1)

调用插入一系列项目的insert方法,请参阅此处列出的第三种方法:

http://msdn.microsoft.com/en-us/library/zcww84w5(v=vs.71).aspx

然后,创建自己的STL样式迭代器来访问要插入的项目。参见:

Custom Iterator in C++

答案 2 :(得分:0)

<强>输入:

Deque:lengtl = l,

新项目(m =新项目数量)

<强> ALGO:

创建一个新的deque(1)

将所有项目从原始deque复制到您要插入新项目的位置(p)

添加新项目(m)

从旧deque(m-p)

添加项目

也许你可以使用新的双端队列,但最糟糕的是:

将新的deque复制到旧的deque上(完全清除后:):

成本(l + m)

因此成本最差:origsize * 2 + newitems是线性的。

这里没有计算“清晰牌组”,但它也是线性的(最坏的情况下)。

答案 3 :(得分:0)

将插入点之后的所有元素添加到向量中 插入点后删除所有元素 为deque添加新范围。
将矢量附加到双端队列。

这是O(2n)最坏的情况,而不是O(n ^ 2)。