STL deque是作为循环链表实现的吗?

时间:2011-04-05 22:42:02

标签: c# c++ stl

我无法找到如何在C ++ STL中实现deque的内部结构。

我之前在某处读过它,在C#中它被实现为循环列表。它也适用于C ++ STL吗?另外,你能解释为什么会这样吗?

编辑:C ++ STL,我的意思是Visual Studio C ++ 2010附带的STL库,以及与gcc一起发布的STL库

4 个答案:

答案 0 :(得分:8)

没有。它的实现方式允许有一些变化,但循环链表确实符合条件。

在大多数实现中(包括VC ++和gcc),它基本上是指向数据块的指针数组。添加数据时,通常只是将其添加到现有数据块中。当现有块变满时,它会分配一个新块,将其添加到您要插入的数组的末尾,然后将数据添加到它。当/如果基本数组空间不足时,它会分配一个新的并在那里复制指针。

答案 1 :(得分:6)

C ++标准要求双端队列具有恒定的随机查找时间。圆形链表不符合要求。

答案 2 :(得分:2)

STL是规范,而不是实现。规范没有要求 必须如何实现行为(只要它遵循定义的接口)。

答案 3 :(得分:2)

deque的实施必须提供

  1. 随时随地访问它的元素
  2. 最后一次插入和移除
  3. 开始时不断插入和移除
  4. (1)排除任何类型的链表,包括循环列表

    (2)& (3)排除存储元素的简单内存块。

    注意:当前标准('03)确实说恒定时间而不是摊销的恒定时间(2)& (3)(见23.2.1/1),但我认为这是一种疏忽。我不知道如何在恒定时间内完成所有三个。如果(2)和(3)的常数时间和(2)和(3)的分摊常数时间那么它就相当容易了。

    AFAIK MSVC deque使用指向元素页面的指针的环形缓冲区。将环形缓冲区视为具有偏移量+环绕的数组(vector)。页面包含少量元素(IIRC不超过8个),具体取决于sizeof(element)。如果需要更多空间,则环缓冲区就像std::vector一样增长(这是您需要分摊的常量时间而不是常量时间)。

    我认为其他实现(GCC,......)将非常相似。

    BTW:标准中还有一个条款,它不能仅使用一个大的元素环形缓冲区,而没有“指针索引”。 23.2.1.3/1表示在开头或结尾处的插入使对deque中元素的引用无效。显然,如果保持元素本身的结构在超出保留空间时必须重新分配,那是不可能的。普通的环形缓冲区需要它,所以不能使用它。