鉴于C ++已经具有双端队列,为什么会有队列和堆栈?

时间:2018-11-09 14:11:57

标签: c++ data-structures stl deque

我想知道为什么C ++在已经具有双端队列的情况下具有队列和堆栈。

似乎堆栈/队列的运行时间以及使用双端队列模拟堆栈/队列的时间是相同的。此外,双端队列支持堆栈,队列都不支持的修饰符,如擦除,迭代器和随机访问。

那么,鉴于双端队列比其他两个函数都强大得多,为什么C ++会提供这三个函数呢?

谢谢!

3 个答案:

答案 0 :(得分:7)

std::queuestd::stack实际上不是标准库中的容器。它们是container adaptors,用于在实际容器的顶部为您提供特定的界面。

您不希望您的堆栈具有operator [],因此我们包装std::deque(默认情况下,您可以使用其他容器),以便我们不公开堆栈不会具有的操作

答案 1 :(得分:3)

std::stackstd::queue是所谓的“容器适配器”,因为它们适应包装容器的接口(模板参数,默认为std::deque,但可以是任何为back()实现push_back()pop_back()std::stack,为back()实现pop_front()push_back()std::queue )到堆栈或队列的受限接口;如果您愿意,它们可以使底层容器接口变得愚蠢。

一般的想法应该是“受限制的”容器仅提供容器的“预期操作模式”的操作-std::stack仅允许类似堆栈的操作,而不像基础的{{1} },例如,允许随机插入/访问。另一个优点是,与基础容器类型相比,在基础容器类型上的编译时多态性要舒适一些(您可能会得到更好的错误消息)。

在实践中,我总是发现这些适配器至少没有用,而更多的只是障碍:

  • 它们不限制可用状态的空间,因为给定额外的空间,std::dequestd::stack都可以以任何方式进行突变;
  • 由于它们是模板参数,因此它们不提供对基础容器类型的类型擦除,因此,编写不占用任何堆栈的非模板函数(无论基础容器如何)对它们无用;
  • 大多数情况下,它们的界面过于受限;即使基础容器完全支持前向迭代器(甚至是随机访问),您甚至都无法对std::queue的全部内容进行调试打印。

答案 2 :(得分:1)

std::stackstd::queue都是容器适配器。默认情况下,使用std::deque作为后备容器,但不一定如此。

与双端队列相比,堆栈和队列的接口都减少了。因此,您可能想要一个不使用std::deque而是使用其他容器的堆栈,而这正是适配器的用途。