【问题标题】:Does deque provide O(1) complexity when inserting on top在顶部插入时,双端队列是否提供 O(1) 复杂性
【发布时间】:2014-04-13 22:57:28
【问题描述】:

我正在查看this 的帖子,它指出双端队列在顶部和底部提供了有效的插入。但是这里的post 指出除了后面之外的双端队列的时间复杂度是 O(n)。我认为如果双端队列具有有效的顶部和底部插入,它将具有 O(1) 而向量应该仅在底部插入时具有 O(1)。如果有人能澄清这一点,我将不胜感激

【问题讨论】:

标签: c++ vector stl deque


【解决方案1】:

std::deque 的 cppreference 条目具有以下复杂性:

deques上常见操作的复杂度(效率)如下:

  • 随机访问 - 常数 O(1)
  • 在末尾或开头插入或删除元素 - 摊销常数 O(1)
  • 插入或删除元素 - 线性 O(n)

这与draft C++ standard 部分23.3.3.1 类模板双端队列概述 一致,它说(强调我的):

双端队列是一个序列容器,与向量 (23.3.6) 一样,支持随机访问迭代器。此外,它还支持在开始或结束时进行恒定时间的插入和擦除操作;在中间插入和擦除需要线性时间。也就是说,双端队列特别针对在开头和结尾推送和弹出元素进行了优化。与向量一样,存储管理是自动处理的。

对于std::vector cppreference 说:

对向量常用操作的复杂度(效率)如下:

  • 随机访问 - 常数 O(1)
  • 在末尾插入或删除元素 - 摊销常数 O(1)
  • 插入或删除元素 - 与向量末端的距离成线性 O(n)

与草案标准部分一致23.3.6.1类模板向量概述

向量是支持随机访问迭代器的序列容器。另外,它支持(摊销的)常数时间的最后插入和擦除操作;中间插入和擦除需要线性时间。存储管理是自动处理的,但可以给出提示以提高效率。[...]

【讨论】:

  • 向量是否在两端或仅在末尾有 0(1) 插入?
  • 要么他们改变了 cppreference 中的措辞,要么你引用错误,但在 deque 的末端插入/删除的复杂性被列为常数 O(1) not 摊销常数 O (1)。这显然很重要,但作为旁注,对于我的一生,我无法弄清楚 O(1) 的常数是多少。
【解决方案2】:

来自 C++ 标准:

23.3.3.4 双端队列修饰符 [deque.modiifiers]

[...]
void push_front(const T& x);
void push_front(T&& x);
void push_back(const T& x);
void push_back(T&& x);

[...]

3 复杂度:复杂度与插入的元素数量加上到双端队列开头和结尾的距离中的较小者成线性关系。 在双端队列的开头或结尾插入单个元素总是需要恒定的时间,并导致对 T 的构造函数的单次调用。

强调我的

【讨论】:

    【解决方案3】:

    C++98,第 23.2.1 节(模板类双端队列)

    “deque ...支持在开始或结束时进行恒定时间的插入和擦除操作;在中间插入和擦除需要线性时间。也就是说,deque 特别针对在开始和结束。与向量一样,存储管理是自动处理的。”

    所以是的:在两端插入 O(1)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 2011-01-18
      • 2016-10-31
      • 2019-07-28
      • 2020-08-10
      • 1970-01-01
      相关资源
      最近更新 更多