C++ Primer(中文版)(第五版)【读书笔记】

  • 第 9 章 顺序容器
    • 9.1 顺序容器概述
    • 9.2 容器库概览
      • 9.2.1 迭代器
      • 9.2.2 容器类型成员
      • 9.2.3 begin 和 end 成员
      • 9.2.4 容器定义和初始化

第 9 章 顺序容器

顺序容器:存储元素,元素位置由加入容器时顺序决定。
关联容器:存储元素,元素位置由关键字 key 决定。

所有容器共享公共接口,各自实现不同。

9.1 顺序容器概述

顺序容器:快速顺序访问元素。

性能代价:

  • 添加和删除元素。
  • 非顺序访问。

vector:可变大小数组。支持随机访问(连续内存存储)。尾部插入或删除元素时间复杂度为O(1),其他位置插入或删除元素时间复杂度为O(n)。
deque:双端队列。支持随机访问(连续内存存储)。

顺序容器类型 说明 访问 头插 O 头删 O 尾插 O 尾删 O 除头尾位置插入或删除 查找元素时间复杂度
vector 可变大小数组。 快速随机访问。 不支持 不支持 O(1) O(1) O(n) O(n)
deque 双端队列。 快速随机访问。 O(1) O(1) O(1) O(1) O(n) O(n)
list 双向链表。 只支持双向顺序访问。 O(1) O(1) O(1) O(1) O(1) O(1)
forward_list 单向链表。 只支持单向顺序访问。 O(1) O(1) O(1) O(1) O(1) O(1)
array 固定大小数组。 快速随机访问。 不支持 不支持 不支持 不支持 不支持 不支持
string 与 vector 相似,保存字符的容器。 快速随机访问。 不支持 不支持 O(1) O(1) O(n) O(n)

除 array 其他容器支持高效、灵活的内存管理,可以添加、删除元素,扩张和收缩容器大小。

存储策略影响容器支持的操作。

array 比内置数组更安全,更容易使用。

forward_list 没有 size 操作,其他容器 size 是常量时间操作。

尽可能使用C++标准库。

确定使用哪种顺序容器:

  • 没有理由选择其他容器,就选择 vector。
  • 随机访问,选择 vector 或 deque。
  • 插入删除数据,list 或 forward_list。
  • 头和尾插入或删除元素,中间位置不会,选择 deque。
  • 读取输入时插入,随后随机访问:①.vector 追加,标准库 sort 重排。②.输入list,完成输入后 list 拷贝到 vector。
  • 随机访问 + 中间位置插入删除:应用中占主导地位的操作决定。

不确定,只使用 vector 和 lsit 的公共操作:使用迭代器,不使用下标,避免随机访问。
切换容器方便。

9.2 容器库概览

容器定在与类型名相同的头文件中。

容器是模板,提供额外信息生成特定容器类型。

容器元素可以是任意类型。

为不支持特定操作的类型定义容器,就只能使用没有特殊要求的容器操作:

顺序容器构造函数一个版本接受容器大小,使用元素类型的默认构造函数。某些类没有默认构造函数,定义一个保存这种类型对象的容器,构造容器是不能只传递元素数目参数:

//noDefault 没有默认构造函数
vector<noDefault> v1(10, init);	//提供元素初始化器。
vector<noDefault> v1(20);	//错误,必须提供元素初始化器。
类型别名 类型 作用
iterator 此容器类型的迭代器类型。 可读可写容器元素。
const_iterator 只读迭代器类型。 只读容器元素。
size_type 无符号整数类型。 容器元素数量。
difference_type 带符号整数类型。 两个迭代器之间的距离。
value_type 元素类型。 获取容器元素类型。
reference value_type & 元素的左值类型。
const_reference const value_type & 元素的 const 左值类型。
构造函数 说明
C c; 默认构造函数,构造空容器。
C c1(c2); 构造 c2 的拷贝 c1。
C c(b, e); 使用迭代器 b 和 e 范围内的元素构造 c。(array不支持)
C c{a, b, c……} 列表初始化c
赋值和swap 说明
c1 = c2 c2 中的元素替换c1 中的元素。
c1 = {a, b, c, ……} 列表元素替换 c1 中的元素。(array不适用)
a.swap(b) 交换 a 和 b 的元素。
swap(a, b) 与 a.swap(b) 等价。
大小 说明
c.size() c 中元素的数量。(forward_list 不支持)
c.max_zise() c 可保存的最大元素数量。
c.empty() 为空返回 true,不为空返回 false。
添加 / 删除元素(不适用 array)【注:不同容器操作接口不同】 说明
c.insert(args) 将 args 中的元素拷贝进 c。
c.emplace(inits) 使用 inits 构造 c 中的一个元素。
c.erase(args) 删除 args 指定的元素。
c.clear() 删除 c 中所有元素,返回 void。
关系运算符 说明
==, != 所有容器都支持。
<, <=, >, >= 无序关联容器不支持。
获取迭代器 说明
c.begin(), c.eng() 返回 c 的首元素和尾元素之后位置的迭代器。
c.cbegin(), c.ceng() 返回 const_iterator
反向容器的额外成员。(forward_list不支持) 说明
reverse_iterator 逆序寻址元素的迭代器。
const_reverse_iterator 不可修改的逆序寻址元素的迭代器。
c.rbegin(), c.rend() 返回指向 c 的尾元素和首元素之前位置的迭代器。
c.crbegin(), c.crend() 返回 const_reverse_iterator

9.2.1 迭代器

提供相同操作的迭代器对操作的实现方式相同:
所有迭代器都允许访问容器中的元素且都通过解引用来实现。
所有迭代器都定义了递增运算符,从当前元素移动到下一个元素。

forward_list 不支持迭代 --。

支持迭代器算术运算:string、vector、deque 和 array。(这些容器底层内存连续存储空间)

迭代器范围:[begin, end)

迭代器范围要求:(程序员的责任)

  • begin 和 end 必须指向同一容器。
  • end 可以与 begin 指向相同的位置,但不能指向 begin 之前的位置。
  • begin == end ,范围为空。
  • begin 和 end 不等,至少包含一个元素,begin指向范围的第一个元素。
  • 可以对 begin 递增若干次,begin == end。

9.2.2 容器类型成员

类型别名 类型 作用
iterator 此容器类型的迭代器类型。 可读可写容器元素。
const_iterator 只读迭代器类型。 只读容器元素。
size_type 无符号整数类型。 容器元素数量。
difference_type 带符号整数类型。 两个迭代器之间的距离。
value_type 元素类型。 获取容器元素类型。
reference value_type & 元素的左值类型。
const_reference const value_type & 元素的 const 左值类型。

9.2.3 begin 和 end 成员

begin 生成指向容器中的第一个元素的迭代器。
end 生成指向容器中的尾元素之后位置的迭代器。

获取迭代器 说明
c.begin(), c.eng() 返回 c 的首元素和尾元素之后位置的迭代器。
c.cbegin(), c.ceng() 返回 const_iterator
反向容器的额外成员。(forward_list不支持) 说明
reverse_iterator 逆序寻址元素的迭代器。
const_reverse_iterator 不可修改的逆序寻址元素的迭代器。
c.rbegin(), c.rend() 返回指向 c 的尾元素和首元素之前位置的迭代器。
c.crbegin(), c.crend() 返回 const_reverse_iterator

r:反向迭代器。
c:返回 const 迭代器。
不以c开头的函数被重载过,const 成员返回 const_iterator。no-const 成员返回 iterator。

no-const 对象返回 iterator。
const 对象返回 const_iterator。

iterator 可以转换为 const_iterator,反之则不行。

auto 可以和 being 、end结合使用,结果依赖于容器类型。

不需要写时,使用 cbegin 和 cend。

9.2.4 容器定义和初始化

你可能感兴趣的:(读书笔记,C++,c++)