- 顺序容器概述
顺序容器 | 存取 | 插入删除 |
---|---|---|
vector(可变大小数组) | 快速随机存取 | 尾部快,其他慢 |
deque(双端队列) | 快速随机存取 | 前端尾部快 |
list(双向链表) | 双向顺序存取 | 所有位置都很快 |
forward_list(单向链表) | 单向顺序存储 | 所有位置都很快 |
array(固定大小数组) | 快速随机存取 | 不能插入删除元素 |
string | 快速随机存取 | 尾部快,其他慢 |
- 定义与初始化容器
容器的定义与初始化方式有:
// 适用于所有容器类型
ContainerType container; // container不是array类型则为空, 否则默认初始化
ContainerType container1(container2); // container1初始化为container2的拷贝
ContainerType container1 = (container2); // container1初始化为container2的拷贝
ContainerType container{element1, element2...}; // 列表初始化
ContainerType container = {element1, element2...}; // 列表初始化
containerType container(iterator1, iterator2); // container初始化两迭代器之间元素的拷贝
// 只适用于顺序容器(除array容器)
SequeContType seqCon(n); // seqCon有n个元素, 执行值初始化, 不适用string
SequeContType seqCon(n, elem); // seqCon包含n个值为elem的元素
- 容器赋值与swap
容器的赋值方式:
// 适用于所用容器
container1 = container2; // container2赋值给container1
container = {elem1, elem2,...}; // 列表中元素赋值给container, array不适用
container1.swap(container2); // container1与container2元素交换
// 不适用于关联容器和array
seqCon.assign(iter1, iter2); // iter1与iter2之间的元素赋给seqCon
seqCon.assign(n, elem); // n个ele元素赋给seqCon
assiign
操作不适用关联容器和array
- 容器大小操作
两容器可以使用>, <, >=, <=, ==, !=
进行关系运算:
- 如果两容器具有相同大小且所有元素都两两对应相等, 则两个容器相等, 否则不等.
- 如果两个容器大小不同, 但是较小容器中每个元素都等于较大容器中的对应元素, 则较小容器小于较大容器.
- 如果两个容器都不是另一个容器的前缀子序列, 那么比较结果取决于第一个不想等的元素比较结果.
以上容器操作适用于所有容器
- 向顺序容器添加元素
向顺序容器中添加元素主要有push, inset, emplace
三种操作.
// push_back
seqCon.push_back(elem); // 在seqCon的尾部添加一个值为elem的元素, 返回void
// push_front
seqCon.push_front(elem); // 在seqCon的头部添加一个值为elem的元素, 返回void
// insert
seqCon.insert(iter, elem); // 在迭代器iter所指位置之前插入一个值为elem的元素, 返回指向新添加元素的迭代器
seqCon.insert(iter, num, elem); // 在迭代器iter所指位置之前插入num个值为elem的元素, 返回指向新添加的第一个元素的迭代器
seqCon.insert(iter, iterBeg, iterEnd); // 将迭代器iterBeg和iterEng指定范围内的元素插入到迭代器iter指向的元素之前, iterBeg iterEnd不能指向seqCon的元素, 返回指向新添加第一个元素的迭代器, 若iterBeg==iterEnd则返回iter
seqCon.insert(iter, initList); // initList是花括号包围的元素值列表, 将这些元素插入到iter所指位置之前, 返回新添加第一个元素的迭代器, 若列表为空, 返回iter
// emplace_front
seqCon.emplace_front(args); // args是构造seqCon的元素所用的参数, 在seqCon的头部添加一个值为elem的元素, 返回void
// emplace_end
seqCon.emplace_end(args); // args是构造seqCon的元素所用的参数, 在seqCon的尾部添加一个值为elem的元素, 返回void
// emplace
seqCon.emplace(inter, args); // args是构造seqCon的元素所用的参数, 在迭代器iter所指位置之前插入一个由args构造的函数, 返回指向新添加元素的迭代器
array
不能改变大小, 不支持向array中添加元素.
forward_list
有自己专用版的insert
和emplace
forward_list
不支持push_back
和emplace_back
vector
和string
不支持push_front
和emplace_front
- 访问顺序容器的元素
访问顺序容器元素的主要方法有:
seqCon.front(); // 返回seqCon头元素的引用, 若seqCon为空, 则函数行为未定义
seqCon.back(); // 返回seqCon尾元素的引用, 若seqCon为空, 则函数行为未定义
seqCon.at(n); // 返回下标为n的元素的引用, 若下标越界则抛出异常
seqCon[n]; // 返回下标为n的元素的引用, 若下标越界则函数行为未定义
at
和下标操作不适合list, forward_list
back
不适合forward _list
- 删除顺序容器元素
删除顺序容器元素的主要操作有:pop erase clear
// pop
seqCon.pop_front(); // 删除首元素, 若seqCon为空, 则函数行为未定义, 函数返回void
seqCon.pop_back(); // 删除尾元素, 若seqCon为空, 则函数行为未定义, 函数返回void
// erase
seqCon.erase(iter); // 删除iter所指元素, 返回被删元素之后元素的迭代器或尾后迭代器
seqCon.erase(iterBeg, iterEnd); // 删除iterBeg和iterEnd之间的元素, 返回最后一个被删元素之后元素的迭代器或尾后迭代器
// clear
seqCon.clear(); // 删除seqCon中所有元素, 返回void
所有删除操作都不适合
array
- 改变顺序容器大小
resize
函数可以用来增大或者缩小容器.
list<int> intList(10, 77); // 10个int, 每个值都是77
// resize
intList.resize(15); // 改变大小为15, 前10个元素为原元素, 后5个初始化为0
intList.resize(15, -1); // 改变大小为15, 前10个元素为原元素, 后5个初始化为-1
intList.resize(5); // 改变大小为5, 删除原容器后5个元素
resize
操作不适合array
- 迭代器失效
向容器添加或删除元素的操作可能使得指向容器元素的指针, 引用, 迭代器失效. 向容器添加元素:
- 如果容器是vector或者string, 且存储空间被重新分配则迭代器, 指针, 引用都会失效; 若存储空间未重新分配, 则指向插入位置之前的元素的迭代器, 指针, 引用有效, 之后的无效.
- 如果容器是deque, 插入到首尾位置之外的任何位置都会导致迭代器, 指针, 引用失效. 插入到首尾位置会导致迭代器失效, 指针, 引用有效.
- 如果容器是list和forward_list, 则所有迭代器, 指针, 引用都有效.
从容器删除元素:
- 如果容器是vector或者string, 指向被删除元素之前的迭代器, 指针, 引用仍有效.
- 如果容器是deque, 在首尾之外的任何位置删除元素, 那么指向被删除元素之外其他元素的迭代器, 引用, 和指针失效. 删除首元素, 迭代器, 指针, 引用都不受影响. 删除尾元素, 除尾后迭代器外其他不受影响.
- 如果容器是list和forward_list, 则所有迭代器, 指针, 引用都有效.
1.在循环中要向容器添加或删除元素时要根据函数返回迭代器的指向及时更新迭代器
2. 不要保存end返回的尾后迭代器, 需要尾后迭代器时随时调用end()
函数