顺序容器
顺序容器表格类型 | |
---|---|
vector | 可变大小的数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。 |
deque | 双端队列。支持快速随机访问。在头尾位置插入/删除很快。 |
list | 双向链表。只支持双向顺序访问。在list中任意位置进行插入/删除操作都很快。 |
forward_list | 单向链表。只支持单向顺序访问。在链表的任何位置进行插入/删除操作都很快。 |
array | 固定大小数组。支持快速随机访问。不能添加或删除元素。 |
string | 与vector类似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除很快。 |
例如,string 和vector将元素保存在连续的内存空间中。由于元素是连续存储的,由元素的下标来计算其地址是非常快速的。
但是,在这两种容器的中间位置添加或删除元素就会非常耗时:在一次插入或删除操作后,需要移动插入/删除位置之后的所有元素,来保持连续存储。
而且,添加一个元素有时可能还需要分配额外的存储空间。在这种情况下,每个元素都必须移动到新的存储空间中。
list 和 forward_1ist 两个容器的设计目的是令容器任何位置的添加和删除操作都很快速。作为代价,这两个容器不支持元素的随机访问:为了访问一个元素,我们只能遍历整个容器。而且,与 vector、deque 和 array 相比,这两个容器的额外内存开销也很大。
forward_list 和array是新 C++标准增加的类型。与内置数组相比,array是一种更安全、更容易使用的数组类型。与内置数组类似,array对象的大小是固定的。因此, array不支持添加和删除元素以及改变容器大小的操作。
forward_list的设计目标是达到与最好的手写的单向链表数据结构相当的性能。因此,forward_1ist 没有 size操作,因为保存或计算其大小就会比手写链表多出额外的开销。对其他容器而言,size保证是一个快速的常量时间的操作。
确定使用哪种顺序容器
以下是使用容器的基本规则
- 除非你有很好的理由选择其他容器,否则应使用 vector。
- 如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用 list 或 forward_list。
- 如果程序要求随机访问元素,应使用 vector 或 deque。
- 如果程序要求在容器的中间插入或删除元素,应使用list或 forward_list。如果程序需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用 deque。
- 如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素,则
- 首先,确定是否真的需要在容器中间位置添加元素。当处理输入数据时,通常可以很容易地向 vector 追加数据,然后再调用标准库的 sort 函数来重排容器中的元素,从而避免在中间位置添加元素。
- 如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将 list 中的内容拷贝到一个 vector 中。
如果你不确定应该使用哪种容器,那么可以在程序中只使用 vector和list公共的操作:使用迭代器,不使用下标操作,避免随机访问。这样,在必要时选择使用 vector 或 list 都很方便。