核心简记
容器分为顺序容器(不依赖值,与元素加入位置对应)、有序与无序关联容器(根据关键字的值存储)。标准库的容器性能很好
顺序容器类型:在添加删除与查找方面代价侧重不同。
- vector:可变大小数组,随机访问,尾部插入快。 空间不够时分配更大的,并拷贝
- deque:双端队列,随机访问,头尾插入快 。 一段一段的连续空间链接起来,deque采用一块map(非STL中的map)作为主控,map是一块小的连续空间,其中每个元素都是指针,指向一块较大的线性连续空 间,称为缓冲区。而缓冲区才是存储deque元素的空间主体。
- list:双向链表,双向顺序访问,任意插入快 。 底层数据结构为双向循环链表
- forward_list:单向链表,单向顺序访问,任意插入快
- array:固定大小数组,随机访问,不可改动大小
- string:与vector相似,专门保存字符。
容器上的操作层次:
- 所有容器类型提供
- 仅针对顺序、关联或无序容器
- 只适用小部分容器
每个容器定义在头文件中,文件名与类型名相同。均为模板类
所有容器都适用的操作
|
|
迭代器是仿指针的类实现,标准库使用范围是左闭右开[),原因:
- begin与end相等则范围为空
- b与e不等则至少含一个元素
- b递增若干可等于e
这样在许多算法实现中都不用考虑区间问题。一旦改变容器大小,迭代器失效。虽然有的不会失效但防止错误需要时再细看。
拷贝构造类型必须相同,不过用迭代器构造时不必相同,可转化即可。
array的模板中大小也是类型一部分 array< int , 42 > 类型一部分。
容器的比较是进行元素的逐个比较,空<一切。元素以第一个不同的为整体比较结果。元素需要定义==与<
顺序容器操作
顺序容器添加:
传入元素对象时传入的是拷贝。emplace版本是直接构造。
deque保证容器首尾插入删除都是常数时间。
访问操作:
引用,为左值。auto只能当类型的前半部分,不会自动加&。左值给auto时防止拷贝要加&。
删除元素:
特殊的forward_list操作
因为forwa_list想添加删除必须改前节点,因此只能决定后节点动作。
改变容器大小
vector特有
vector、string分配空间时往往分配比需求大的,因为每次超出都将全部拷贝,这样有效防止拷贝次数。
因此有:capacity操作告诉我们容器在不扩张内存空间的情况下可以容纳多少个元素
超过才分配
string特有
构造string的方法还有
子字串
改变str其它方法:
搜索操作
compare
类似strcmp,根据s是等于、大于还是小于参数指定的字符串,s.compare返回0,正数和负数。其参数:
数据转化
容器适配器
三个顺序容器适配器:
stack 栈,要求back操作
queue 对列,要求back、front 先进先出
priority_queue 优先级队列,还要求随机访问 加入的会按优先级排序,使用元素的<确定
一个容器适配器接受已有的容器类型,使其行为看起来像不同的类型。只能使用适配器的操作,不能用原本容器的。
所以容器适配器都支持的操作和类型
使用: stack< int ,vector< int >> 第二个模板参数可选,stack、queue默认基于deque。priority_queue默认vector。
栈操作
对列操作
反汇编
这里没什么汇编上的新知识…主要是模板的汇编,在自定义模板时再分析。