Chapter 9: Sequential Containers

本文详细介绍了C++标准库中的顺序容器,包括vector、deque、list、forward_list和array的特点及应用场景。探讨了容器的定义、初始化、赋值、大小操作、元素添加与删除的方法,并讨论了迭代器的有效性和失效情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 顺序容器概述
顺序容器存取插入删除
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


  • 容器大小操作
    两容器可以使用 >, <, >=, <=, ==, != 进行关系运算:
    1. 如果两容器具有相同大小且所有元素都两两对应相等, 则两个容器相等, 否则不等.
    2. 如果两个容器大小不同, 但是较小容器中每个元素都等于较大容器中的对应元素, 则较小容器小于较大容器.
    3. 如果两个容器都不是另一个容器的前缀子序列, 那么比较结果取决于第一个不想等的元素比较结果.

以上容器操作适用于所有容器


  • 向顺序容器添加元素
    向顺序容器中添加元素主要有 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 有自己专用版的 insertemplace
forward_list 不支持 push_backemplace_back
vectorstring 不支持 push_frontemplace_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


  • 迭代器失效
    向容器添加或删除元素的操作可能使得指向容器元素的指针, 引用, 迭代器失效.
  • 向容器添加元素:

    1. 如果容器是vector或者string, 且存储空间被重新分配则迭代器, 指针, 引用都会失效; 若存储空间未重新分配, 则指向插入位置之前的元素的迭代器, 指针, 引用有效, 之后的无效.
    2. 如果容器是deque, 插入到首尾位置之外的任何位置都会导致迭代器, 指针, 引用失效. 插入到首尾位置会导致迭代器失效, 指针, 引用有效.
    3. 如果容器是list和forward_list, 则所有迭代器, 指针, 引用都有效.
  • 从容器删除元素:

    1. 如果容器是vector或者string, 指向被删除元素之前的迭代器, 指针, 引用仍有效.
    2. 如果容器是deque, 在首尾之外的任何位置删除元素, 那么指向被删除元素之外其他元素的迭代器, 引用, 和指针失效. 删除首元素, 迭代器, 指针, 引用都不受影响. 删除尾元素, 除尾后迭代器外其他不受影响.
    3. 如果容器是list和forward_list, 则所有迭代器, 指针, 引用都有效.

1.在循环中要向容器添加或删除元素时要根据函数返回迭代器的指向及时更新迭代器
2. 不要保存end返回的尾后迭代器, 需要尾后迭代器时随时调用 end() 函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值