aJ.*_*aJ. 116
让我列出差异:
复杂
Insert/erase at the beginning in middle at the end
Deque: Amortized constant Linear Amortized constant
List: Constant Constant Constant
Run Code Online (Sandbox Code Playgroud)
fbr*_*eto 50
deque非常像向量:像vector一样,它是一个支持随机访问元素的序列,在序列末尾插入和删除元素的恒定时间,以及中间元素的线性时间插入和删除.
deque与vector不同的主要方式是deque还支持在序列开始时恒定时间插入和删除元素.此外,deque没有任何类似于vector的capacity()和reserve()的成员函数,并且不提供与这些成员函数关联的迭代器有效性的任何保证.
以下是list来自同一网站的摘要:
列表是双重链表.也就是说,它是一个支持前向和后向遍历的序列,以及(开始)(开始)常量时间插入和删除元素的开始或结束,或中间.列表具有重要的属性,即插入和拼接不会使列表元素的迭代器无效,甚至删除也只会使指向被删除元素的迭代器无效.可以更改迭代器的顺序(也就是说,list :: iterator在列表操作之后可能具有与之前不同的前导或后继),但迭代器本身不会失效或被指向不同的元素,除非该失效或突变是明确的.
总之,容器可能具有共享例程,但这些例程的时间保证因容器而异.考虑到使用的这些容器的一个任务时,这是非常重要的:考虑到如何容器将使用最频繁的(例如,更比的插入/删除搜索)走一段很长的路在指导你正确的容器.
lge*_*get 15
我为 C++ 课上的学生制作了插图。这是(松散地)基于(我的理解)GCC STL实现中的实现( https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/ stl_deque.h和https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_list.h)
集合中的元素存储在内存块中。每个块的元素数量取决于元素的大小:元素越大,每个块越少。潜在的希望是,如果无论元素的类型如何,块的大小都相似,那么大多数时候这应该对分配器有帮助。
您有一个列出内存块的数组(在 GCC 实现中称为映射)。所有内存块都已满,除了第一个内存块(可能在开头有空间)和最后一个内存块(可能在末尾有空间)。地图本身是从中心向外填充的。与 a 相反std::vector,这就是如何在恒定时间内完成两端的插入。与 a 类似std:::vector,可以在恒定时间内进行随机访问,但需要两个间接而不是一个。与 类似std::vector或相反std::list,在中间删除或插入元素的成本很高,因为您必须重新组织大部分数据结构。
双向链表可能更常见。每个元素都存储在自己的内存块中,独立于其他元素进行分配。在每个块中,您都有元素的值和两个指针:一个指向前一个元素,一个指向下一个元素。它使得在列表中的任何位置插入元素变得非常容易,甚至将元素的子链从一个列表移动到另一个列表(称为splicing 的操作):您只需更新插入开始和结束处的指针观点。缺点是要通过索引找到一个元素,您必须遍历指针链,因此随机访问在列表中的元素数量方面具有线性成本。
另一个重要的保证是每个不同容器在内存中存储数据的方式:
请注意,deque 旨在尝试平衡 vector 和 list 的优点,而没有各自的缺点。它是内存受限平台(例如微控制器)中的一个特别有趣的容器。
内存存储策略经常被忽视,然而,它往往是为某个应用选择最合适的容器的最重要原因之一。