- 动态大小(理论上无限制,但实际上几千个应该足够了)
- 有序,但允许在任意位置重新排序和插入。
- 允许删除
- 索引访问 - 随机访问
- 计数
在我编写链表之前,是否有任何内置类应该知道?
原始回答: 那听起来像是标准库中的std::list
(双向链表)。
新回答: 在规格更改后,只要元素不超过几千个且向量中没有大量插入和删除,std::vector
可能会起作用。在向量操作的低常数被权衡的情况下,中间插入和删除的线性复杂度可能会被权衡。如果您只在开头和结尾进行了大量插入和删除,则std::deque
也可能适用。
您没有指定足够的要求来选择最佳容器。
动态大小(理论上无限,但实际上几千应该足够)
STL容器被设计为根据需要增长。
有序,但允许重新排序和在任意位置插入。
允许重新排序?std::map 不能被重新排序:您可以从一个 std::map 中删除并插入到另一个使用不同排序的 std::map 中,但作为不同的模板实例化,这两个变量将具有不同的类型。std::list 有一个 sort()
成员函数[感谢 Blastfurnace 指出这一点],特别适用于大对象。一个 std::vector 可以使用非成员 std::sort()
函数轻松重新排序,特别适用于微小对象。
在任意位置进行高效插入可以在 map 或 list 中完成,但是如何找到这些位置呢?在列表中,搜索是线性的(您必须从某个已知的地方开始,并向前或向后逐个元素扫描)。std::map 提供了高效的搜索,已经排序的 vector 也是如此,但是插入到 vector 中涉及移动(复制)所有后续元素以腾出空间:在事物的计划中,这是一个昂贵的操作。
允许删除。使用映射或哈希映射可以快速查找和轻松插入/删除,但无法重新排序。但是,您可以使用另一种排序标准将数据轻松移动到另一个映射中(效率适中)。
向量允许快速搜索和原地重新排序,但最坏的插入/删除性能。对于使用元素索引进行随机访问查找,它是最快的。
-插入和删除:任何STL容器都可以实现这一点,但问题在于执行此操作需要多长时间。任何链表容器(list、map、set)都可以在常数时间内完成,而类似数组的容器(vector)则需要线性时间(具有恒定分摊分配)。
-排序:考虑到您可以随时保持已排序的集合,这不是什么问题,任何STL容器都允许这样做。对于map和set,您不必做任何事情,它们已经在任何时候都会保持集合排序。对于vector或list,您必须进行这项工作,即必须对新元素的位置进行二进制搜索,并将其插入到那里(但STL算法具有您所需的所有部件)。
-重新排序:如果您需要按照规则A对当前已排序的集合进行重新排序,并按照规则B对集合进行重新排序,则可能会出现问题。像map和set这样的容器是由排序规则参数化的(作为类型),这意味着要重新排序,您必须从原始集合中提取每个元素,并将它们插入到具有新排序规则的新集合中。但是,如果您使用vector容器,则可以随时使用STL sort函数以任何您喜欢的规则进行重新排序。
-随机访问:你说你需要随机访问。就我个人而言,我的随机访问定义是指集合中的任何元素都可以在常数时间内(通过索引)访问。根据这个定义(我认为这是相当标准的),任何链表实现都不符合要求,只能使用类似数组的容器(例如std::vector)。map
和set
实现,尽管我从未在实践中见过这种情况。 - Matthieu M.