第九章 顺序容器
1.容器的定义
顺序容器对应数据结构中的线性结构,在STL中,vector、list、deque作为基础容器,都是已经实现了,stack、queue、priority_queue则是作为适配器,即关联一个基础容器来实现自己的功能
容器中元素的初始化和整个容器的内存分配不是同步的
容器只是一个类型元素的集合,在数组的基础上加入了一些控制,使得比数组更易使用,对于基本类型,使用时候没有什么要考虑的,对于类类型,要考虑初始化时候它的构造函数是否需要参数。
2.迭代器
不同的容器类型会有不同的迭代器构造,如vector就是原生态指针,list就是结构体指针,在该结构体指针上重载++,--等操作
对于迭代器的范围,设计者参照哨兵模式,第一个迭代器begin指向容器开始的地方,第二个迭代器end指向一个哨兵,当begin==end的时候表示迭代器遍历完成,
这样设计的好处就是当容器为空时,能使判断标准保持一致;如果设计成当begin>end时候表示遍历结束,也可以,但是要改变begin和end的初始值,end指向begin的前一个位置,这样设计不太美观
当进行删除或插入操作时,
可能会造成容器失效
3.容器的操作
按照STL规范,c++的容器操作都应该基于迭代器的,迭代器类型在容器内部定义,迭代器是链接容器和泛型算法的桥梁
容器的插入操作都是插入在指定迭代器之前,所以如果要在容器末尾插入元素,需要调用push_back(T)
vector和deque重载了下标操作符,可以利用c[n]来访问元素
swap操作用来交换两个容器的内容,由于该操作只是更改指针指向,所以速度很快
第十章 关联容器
STL库定义了一个pair类型,有两个元素first和second,分别表示key和value
1.定义
关联容器不能以容器大小作为参数进行初始化,因为这样无法知道初始化的键对应的什么值
关联容器保存的只是一些键值对,并希望能够很快的查找这些键所对应的值,对键值对的存储前后关系不关心,所有没有push_front和push_back等操作提供给用户
2.操作
关联容器的所有操作也是基于迭代器的,对于插入操作,迭代器没有像序列容器那样可以代表被操作关联容器某个位置,这里的迭代器主要是用来获取内容,例如:
vector<int> c;
c.insert(iter, T);//在iter所指向的位置之前插入T
map<int, int> m;
m.inset(b,e);//插入迭代器b至e之间的所有pair类型元素
m.inset(p);//插入指定的pair类型元素
关联容器的重点在“关联”,关键是能通过key找到value
但是有时也需要排序操作:
如果是按照key排序,如果是c++,在map初始化时候可以重载key的“operator <()"或传入比较函数,如果是java,可以对map对象传入比较函数。
如果是按照value排序,可以把map中的pair传入一个vector,指定vector按value排序,最后得到一个排好序的vector
容器类型也重载了下标运算符,可以使用m[key] = value;//如果key在map中不存在,则插入
第十一章 泛型算法
整个泛型算法都是以迭代器为基础,以迭代器作为基本参数输入,可能带有谓词函数,可能以迭代器作为输出,
其中如果输出end,则表示操作未成功,如find函数
1.谓词函数
谓词函数是返回布尔类型的函数,用来重写算法中的某步判断
sort(beg, end);
sort(beg, end, comp);//comp重写了排序算法中的两元素的比较判断
find(beg, end, val);
find(beg, end, pred);//pred重写了查找元素时候的查找标准
2.迭代器
- 插入迭代器(如inserter):用在泛型算法中,与某个容器绑定,实行指定位置的插入
- iostream迭代器:与输入输出流绑定,迭代遍历所关联的IO流
- 反向迭代器:反向遍历容器,例如:想利用sort进行降序排序但是不想使用谓词函数时候