C ++ deque vs vector和C ++ map vs Set

时间:2010-09-13 20:46:08

标签: c++ stl

有人可以告诉我vector和deque之间的区别是什么。我知道在C ++中实现vector而不是deque。地图和集合的界面看起来与我类似。两者之间有什么区别,何时使用它。

5 个答案:

答案 0 :(得分:48)

std::vector :动态数组类。内部内存分配确保它始终创建一个数组。当数据大小已知且已知不会经常更改时很有用。当你想要随机访问元素时也很好 std::deque :可以充当堆栈或队列的双端队列。当您不确定元素的数量以及访问数据元素时始终以串行方式使用时,这是很好的选择。当从前端和末端添加/移除元素时它们很快,但是当它们被添加到中间或从中间移除时不是很快 std::list :可用于创建数据“列表”的双链表。列表的优点是可以从列表的任何部分插入或删除元素,而不会影响指向列表成员的迭代器(并且在删除后仍然是列表的成员)。当您知道元素将从列表的任何部分经常删除时很有用 std::map :将“密钥”映射为“值”的字典。对于索引不是整数的“数组”这样的应用程序很有用。基本上可用于为元素创建名称的映射列表,例如存储名称到窗口小部件关系的映射。
std::set :“唯一”数据值列表。对于例如如果插入1,2,2,1,3,则列表将只包含元素1,2,3。请注意,此列表中的元素始终是有序的。在内部,它们通常被实现为二叉搜索树(如地图)。

答案 1 :(得分:5)

详情请见此处:

What are the complexity guarantees of the standard containers?

vector Vs deque

deque与矢量相同,但增加了以下内容:

  • 这是一个“前插序列”

这意味着deque与向量相同,但提供了以下额外的保证:

  • push_front()O(1)
  • pop_front()O(1)

设置Vs地图

map是“Pair Associative Container”,而set是“Simple Associative Container”

这意味着它们完全相同。区别在于地图包含项目对(键/值)而不仅仅是一个值。

答案 2 :(得分:1)

set:保存唯一值。将'a'放入两次,该集合有一个'a'。 map:将键映射到值,例如'name'=> 'fred','age'=>你可以查找“名字”,然后你就可以'fred'了。

出队,就像一个向量,但你只能在末尾添加/删除。没有插入中间。 http://en.wikipedia.org/wiki/Deque

编辑:我的出列描述缺失,请参阅下面的评论以进行更正

答案 3 :(得分:1)

地图通常被称为关联数组,通常使用二叉树(例如)实现。 deque是一个双端队列,是链表的某种化身。

这并不是说容器库的实际实现使用了这些概念 - 包含库只会为您提供有关如何访问容器以及以何种(摊销)成本的保证。

我建议你看看一个参考资料,详细介绍这些保证是什么。如果我没记错的话,Scott Meyers的书“有效STL:50种改进标准模板库使用的具体方法”应该谈谈这些。除此之外,C ++标准显然是一个不错的选择。

我真正想说的是:容器确实是由它们的属性描述的,而不是由底层实现来描述。

答案 4 :(得分:1)

std::vector

您的默认顺序容器应该是 std::vector。通常, std::vector 将为您提供性能和速度的正确平衡。 std::vector 容器类似于 C 风格的数组,可以在运行时增长或缩小。底层缓冲区是连续存储的,并保证与 C 风格的数组兼容。

考虑使用 std::vector 如果:

您需要将数据连续存储在内存中 对于 C 风格的 API 兼容性特别有用 你不知道编译时的大小 您需要对元素进行有效的随机访问(O(1)) 您将从末尾添加和删除元素 您想以任何顺序迭代元素 避免使用 std::vector 如果:

您会经常在序列的前面或中间添加或删除元素 缓冲区的大小是恒定的并且事先知道(首选 std::array) 注意 std::vector 的特化:从 C++98 开始,std::vector 被特化为每个元素只占用一位。访问单个布尔元素时,运算符会返回使用该位的值构造的 bool 的副本。

std::array

std::array 容器最像一个内置数组,但提供了额外的功能,如边界检查和自动内存管理。与 std::vector 不同,std::array 的大小是固定的,在运行时不能改变。

考虑使用 std::array 如果:

您需要将数据连续存储在内存中 对于 C 风格的 API 兼容性特别有用 数组的大小是预先知道的 您需要对元素进行有效的随机访问(O(1)) 您想以任何顺序迭代元素 避免使用 std::array 如果:

您需要插入或删除元素 你在编译时不知道数组的大小 您需要能够动态调整数组大小 标准::双端队列 std::deque 容器得名于“双端队列”的缩写。 std::deque 容器在将项目附加到队列的前面或后面时最有效。与 std::vector 不同,std::deque 不提供保留缓冲区的机制。底层缓冲区也不能保证与 C 风格的数组 API 兼容。

考虑使用 std::deque 如果:

您需要在序列的前后插入新元素(例如在调度程序中) 您需要对元素进行有效的随机访问(O(1)) 您希望内部缓冲区在元素被移除时自动收缩 您想以任何顺序迭代元素 避免使用 std::deque 如果:

您需要保持与 C 风格 API 的兼容性 需要提前预留内存 您需要经常从序列中间插入或删除元素 在 std::deque 中间调用 insert 会使所有迭代器和对其元素的引用无效

std::list

std::list 和 std::forward_list 容器实现链表数据结构。 std::list 提供双向链表,而 std::forward_list 仅包含指向下一个对象的指针。与其他顺序容器不同,列表类型不提供对元素的高效随机访问。必须按顺序遍历每个元素。

考虑使用 std::list 如果:

您需要存放很多物品但数量未知 您需要从序列中的任何位置插入或删除新元素 您不需要有效访问随机元素 您希望能够在容器内或不同容器之间移动元素或元素集 你想实现一个节点级的内存分配方案 在以下情况下避免使用 std::list:

您需要保持与 C 风格 API 的兼容性 您需要有效访问随机元素 您的系统使用缓存(首选 std::vector 以减少缓存未命中) 数据的大小是预先知道的,可以通过 std::vector 进行管理