我无法找到如何在C ++ STL中实现deque的内部结构。
我之前在某处读过它,在C#中它被实现为循环列表。它也适用于C ++ STL吗?另外,你能解释为什么会这样吗?
编辑:C ++ STL,我的意思是Visual Studio C ++ 2010附带的STL库,以及与gcc一起发布的STL库答案 0 :(得分:8)
没有。它的实现方式允许有一些变化,但循环链表确实不符合条件。
在大多数实现中(包括VC ++和gcc),它基本上是指向数据块的指针数组。添加数据时,通常只是将其添加到现有数据块中。当现有块变满时,它会分配一个新块,将其添加到您要插入的数组的末尾,然后将数据添加到它。当/如果基本数组空间不足时,它会分配一个新的并在那里复制指针。
答案 1 :(得分:6)
C ++标准要求双端队列具有恒定的随机查找时间。圆形链表不符合要求。
答案 2 :(得分:2)
STL是规范,而不是实现。规范没有要求 必须如何实现行为(只要它遵循定义的接口)。
答案 3 :(得分:2)
deque
的实施必须提供
(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
中元素的引用无效。显然,如果保持元素本身的结构在超出保留空间时必须重新分配,那是不可能的。普通的环形缓冲区需要它,所以不能使用它。