【C++STL】被 List 接口的各种方法搞晕了?关键核心就这几个!

【C++STL】被 List 接口的各种方法搞晕了?关键核心就这几个! 一、list的介绍对于一个容器我们首先要了解它的底层长什么样才能更好的去认识这个容器。像vector它的底层实际上就是一个顺序表而C的list的底层实际上就是一个带头双向链表。在这里插入图片描述以上就是整个链表的结构但要注意这里的结点不是像vector那样是连续的list每个结点之间是不连续的接下来就来看看list的一些核心接口。二、list的使用2.1构造相关的接口只要是学习容器我们一般都从它的构造相关的接口开始看然后再逐步过渡到迭代器增删查改算法这些接口。构造函数接口说明构造函数签名功能描述list(size_type n, const value_type val value_type())构造一个包含n个值为val的元素的list若val未指定则使用默认值list()构造一个空的listlist(const list x)拷贝构造函数通过另一个list对象x构造新listlist(InputIterator first, InputIterator last)通过迭代器区间[first, last)中的元素构造list注意事项默认值行为val参数未提供时使用value_type的默认构造值如int为0类类型调用默认构造函数。迭代器区间[first, last)需为有效的输入迭代器范围左闭右开。拷贝构造新list与x的元素完全独立深拷贝。代码示例代码语言javascriptAI代码解释void list_test1() { //默认构造 listint lit1; //n个val构造 listint lit2(10, 1); //初始化列表构造 listint lt3 { 1,2,3,4,5,6,1,1,1,1}; //拷贝构造 lit4(lit3) listint lit4(lit3); //迭代器区间构造 //listint lit5(lit2.begin()3, lit2.end());list的迭代器不支持这种操作后面会讲 listint lit5(lit2.begin(), lit2.end()); int a[] { 1,2,3,4,5,6,7 }; listint lit6(a, a 3); for (auto e : lit5) { cout e ; } cout endl; }2.2 list的迭代器相关接口函数名返回值类型描述begin迭代器返回指向容器第一个元素的迭代器end迭代器返回指向容器末尾最后一个元素的下一个位置的迭代器rbegin反向迭代器 (reverse_iterator)返回指向容器最后一个元素的反向迭代器即end位置rend反向迭代器 (reverse_iterator)返回指向容器第一个元素前一个位置的反向迭代器即begin位置对于list迭代器的使用与前面类似这里就不给代码示例了。实际上C设计的这种迭代器就是一种展现C封装的特性这使得我们不用去关系各种容器的底层是怎么封装的只管使用这些迭代器就行。因为这些迭代器虽然在底层的实现上可能不同但是在使用上功能和用法都是相似的所以这也是迭代器更底层解耦的体现list迭代器的补充在这里插入图片描述看到这里相信很多读者朋友又会有疑问为什么要将这些迭代器区分开不同容器的迭代器之间有什么不同是按照什么标准来区分的下面就通过一个表格来回答这些问题迭代器类型支持的操作适用的数据结构特性说明单向迭代器单链表、哈希表如 unordered_map仅能沿一个方向移动用于遍历单向结构无法回退。双向迭代器、--红黑树如 map、双向链表如 list可双向移动支持向前和向后遍历适用于需要双向操作的场景。随机迭代器、--、、-、[]string、vector、双端队列 deque支持随机访问可通过下标或指针算术直接访问任意位置元素迭代灵活性最高。注意事项几乎所有的迭代器都支持、*、!这些通用的操作单向迭代器可以看成双向迭代器的特例双向迭代器可以看成随机迭代器的特例也就是单向迭代器能用的算法双向能用随机迭代器也能用。双向迭代器能用的算法随机迭代器也能用代码语言javascriptAI代码解释listint lit5(lit2.begin()3, lit2.end());再来看看这段代码之所以不能这样使用是因为list首先的迭代器是双向迭代器双向迭代器不支持这种操作2.3 空间与元素访问相关接口函数名返回值类型功能描述emptybool检测list是否为空是返回true否则返回falsesizesize_t或等效整型返回list中有效节点的个数frontT模板类型引用返回list的第一个节点中存储值的引用backT模板类型引用返回list的最后一个节点中存储值的引用注意事项front和back通常要求list非空否则可能引发未定义行为如断言错误或异常。size的时间复杂度需根据实现确定如O(1)或O(n)。实际接口可能包含const重载版本如const T front() const。