【C++杂货铺】详解list容器

目录
🌈前言🌈
📁 介绍
📁 使用
📂 构造
📂 迭代器iterator
📂 capacity
📂 modifiers
📂 迭代器失效
📁 模拟实现
📂 迭代器的实现
📂 代码展示
📁 和vector的区别
📁 总结
🌈前言🌈
欢迎收看本期【C++杂货铺】,本期内容将讲解STL中关于list的内容,会分为一下几个方面进行讲解:第一,什么是list,和其他容器的比较;第二,list的常用接口的介绍;第三,从底层除法,模拟实现简易版list;最后,对比和vecotr的主要区别。
以上就是本期要讲解的全部内容了,讲解之前需要你有数据结构中链表的储备知识,是为了更好的理解讲解内容。此外,模拟实现需要类和对象,模板等储备知识,如果只是想简单使用可以只看前两章。
如果你还没有类和对象及模板的知识,可以阅览下面这几篇文章:【C++杂货铺】详解类和对象 [上]-CSDN博客
【C++杂货铺】详解类和对象 [中]-CSDN博客
【C++杂货铺】详解类和对象 [下]-CSDN博客
【C++杂货铺】模板-CSDN博客
📁 介绍
list是可以在常熟范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
list底层是双向链表结构,双向链表中每个元素存储在互不关联的独立节点中,在节点通过指针指向其前一个元素和后一个元素。
和其他的序列式容器相比(vector,array,deque),list通常在任意位置进行插入,移动元素的执行效率更好。
与之相对的,list的最大缺陷是不支持在任意位置的随机访问。

📁 使用
list接口较多,这里简单介绍一些常用的重要接口。
下面是官方文档的链接,对于容器的学习还是要多看文档的。
list - C++ Reference (cplusplus.com)
📂 构造

📂 迭代器iterator

📂 capacity


📂 modifiers

📂 迭代器失效
迭代器失效即迭代器所指向的节点无效,即该节点被删除。因为list底层是带头结点的双向循环链表,因此在list中进行插入时是不会导致迭代器失效的,只有在删除时才会失效,并且失效只是指向所删除结点的迭代器,其他迭代器不会受到影响。
void TestListIterator1()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array+sizeof(array)/sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给
其赋值l.erase(it); ++it;}
}// 改正
void TestListIterator()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array+sizeof(array)/sizeof(array[0]));auto it = l.begin();while (it != l.end()){l.erase(it++); // it = l.erase(it);}
}
📁 模拟实现
对于list的模拟实现最难实现的就是迭代器的实现。所以下面将重点讲解迭代器内容。
📂 迭代器的实现
迭代器就是通过模拟指针,提供一种统一的方法来使用容器。
对于vecotr这样的容器,迭代器可以直接是指针,但对于list这样的容器,不能直接使用原生指针,因为底层内存地址不是连续的。
指针++,并不能实现node = node->next这样的操作。这里就要用到C++的重要组成部分了,运算符重载和实现了类。通过将指针封装成类,来实现运算符重载。
这里迭代器使用三个模板参数,第一个表示数据data的类型,第二表示数据data的引用,第三个表示数据data的地址。
template<class T,class Ref,class Ptr>struct ListIterator{typedef ListNode<T> Node;typedef ListIterator<T,Ref,Ptr> iterator;//构造函数ListIterator(Node* node):_node(node){}Ref operator*(){return _node->data;}Ptr operator->(){return &_node->data;}//++ititerator& operator++(){_node = _node->_next;return *this;}iterator operator++(int){iterator temp(*this);_node = _node->_next;return temp;}//--ititerator& operator--(){_node = _node->_prev;return *this;}iterator operator--(int){iterator temp(*this);_node = _node->_prev;return temp;}// != bool operator!=(const iterator& it){return _node != it._node;}bool operator==(const iterator & it){return _node == it._node;}Node* _node;};
📂 代码展示
下面将list的实现,放在exercise命名空间中。
namespace exercise
{//节点类template<class T>struct ListNode{typedef ListNode<T> Node;Node* _next;Node* _prev;T data;ListNode(const T& val = T()):_next(nullptr),_prev(nullptr),data(val){}};template<class T,class Ref,class Ptr>struct ListIterator{typedef ListNode<T> Node;typedef ListIterator<T,Ref,Ptr> iterator;//构造函数ListIterator(Node* node):_node(node){}Ref operator*(){return _node->data;}Ptr operator->(){return &_node->data;}//++ititerator& operator++(){_node = _node->_next;return *this;}iterator operator++(int){iterator temp(*this);_node = _node->_next;return temp;}//--ititerator& operator--(){_node = _node->_prev;return *this;}iterator operator--(int){iterator temp(*this);_node = _node->_prev;return temp;}// != bool operator!=(const iterator& it){return _node != it._node;}bool operator==(const iterator & it){return _node == it._node;}Node* _node;};//list类template<class T>class list{typedef ListNode<T> Node;public:typedef ListIterator<T,T&,T*> iterator;typedef ListIterator<T,const T&,const T*> const_iterator;void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(const list<T>& l){empty_init();for (auto& e : l){push_back(e);}}void swap(list<T>& temp){std::swap(_head,temp._head);std::swap(_size, temp._size);}list<T>& operator=(list<T> temp) {swap(temp);return *this;}void clear(){iterator it = _head->_next;while (it != _head){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;_size = 0;}iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}/*void push_back(const T& val){Node* newnode = new Node(val);Node* tail = _head->_prev;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;tail->_next = newnode;}*/void push_back(const T& val){insert(end(), val);}void insert(iterator pos, const T& val){Node* newnode = new Node(val);Node* prev = pos._node->_prev;Node* next = pos._node;newnode->_prev = prev;prev->_next = newnode;newnode->_next = next;next->_prev = newnode;_size++;}iterator erase(iterator pos){Node* prev = pos._node->_prev;Node* next = pos._node->_next;delete pos._node;prev->_next = next;next->_prev = prev;_size--;return next;}void pop_back(){erase(--end());}size_t size(){return _size;}private:Node* _head;size_t _size;};}
📁 和vector的区别

📁 总结
以上,就是本期【C++杂货铺】的主要内容了,包含了list的介绍,list常用接口以及模拟实现list。
如果感觉本期内容有帮助到你,欢迎点赞,收藏,关注Thanks♪(・ω・)ノ

相关文章:
【C++杂货铺】详解list容器
目录 🌈前言🌈 📁 介绍 📁 使用 📂 构造 📂 迭代器iterator 📂 capacity 📂 modifiers 📂 迭代器失效 📁 模拟实现 📂 迭代器的实现 &#x…...
使用filezilla连接Ubuntu22.04虚拟机
获取电脑IP和虚拟机IP ① 在windows下ctrlR再输入cmd,打开指令窗口,输入 ipconfig 虚拟机连接电脑用的是NAT模式,故看VMnet8的IP地址 ② 查看虚拟机IP地址 终端输入 ifconfig 如果没安装,按提示安装net-tools sudo apt install …...
Verilog基础【二】
3.1 Verilog 连续赋值 关键词:assign, 全加器 连续赋值语句是 Verilog 数据流建模的基本语句,用于对 wire 型变量进行赋值。: assign LHS_target RHS_expression ;LHS(left hand side)…...
定时推送任务 Apache HttpClient/okhttp3
定时推送任务 需求 需要定时推送我方的数据到对方那边 方法1 Apache HttpClient 此方法指定推送过去的信息转为utf-8格式的json字符串 Scheduled(initialDelay 1000 * 120, fixedDelay 1000 * 60 * 5) public void diseaseInterface() {String lockKey "lock:dise…...
centos7 安装 mysql
命令记录,未整理; 1. 下载mysql5.7的安装包,上传到linux系统某个目录中 2. 使用tar -xvf 解压 tar包 tar -xvf mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar 3. 使用 rpm -ivh 安装 mysql rpm -ivh mysql-community-common-5.7.35-1.el7.x8…...
src挖掘技巧总结分享
src挖洞技术分享 src推荐刚入门的新手首选公益src如漏洞盒子、补天src,因为漏洞盒子收录范围广,只要是国内的站点都收入,相比其它src平台挖掘难度非常适合新手。后续可以尝试先从一些小的src厂商入手。 首先是熟能生巧,我一开始挖…...
【面试八股总结】传输控制协议TCP(一)
一、什么是TCP协议 TCP是传输控制协议Transmission Control Protocol TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。 面向连接的:每条TCP连接杜只能有两个端点,每一条TCP连接只能是点对点的(一对一)可靠的:…...
【系统架构师】-第13章-层次式架构设计
层次式体系结构设计是将系统组成一个层次结构,每一层 为上层服务 ,并作为下层客户。 在一些层次系统中,除了一些精心挑选的输出函数外, 内部的层接口只对相邻的层可见 。 连接件通过决定层间如何交互的协议来定义,拓扑…...
【操作系统】想要更好的学习计算机,操作系统的知识必不可少!!!
操作系统的概念 导言一、日常生活中的操作系统二、计算机系统层次结构三、操作系统的定义3.1 控制和管理计算机资源3.2 组织、调度计算机的工作与资源的分配3.3 给用户和其他软件提供方便接口与环境3.4 总结 四、操作系统的目标和功能4.1 作为管理者4.1.1 处理机管理4.1.2 存储…...
AtCoder Grand Contest 066 B. Decreasing Digit Sums(构造 打表找规律)
题目 给定一个n(n<50),记f(x)是x各数位的加和,例如f(331)3317 要求输出一个x(),且对于任意i∈[1,n],均有成立 思路来源 jiangly B站讲解 题解 首先n没啥用,构造一个n50成立的case即可, 给定一个x…...
Hadoop系列总结
一、Hadoop linux基本操作 前提掌握Linux基本操作 参考 Linux基本操作-CSDN博客 1、查看hadoop指定路径下文件大小前6的文件信息 hdfs dfs[hadoop fs] -du -h /path/to/directory|sort -hr|head -n 6...
【第三方登录】Twitter
创建应用 APPID 和 相关回调配置 重新设置api key 和 api secret 设置回调和网址 还有 APP的类型 拿到ClientID 和 Client Secret 源码实现 获取Twitter 的登录地址 public function twitterUrl() {global $db,$request,$comId;require "inc/twitter_client/twitte…...
C++经典面试题目(十七)
1、请解释拷贝构造函数的作用,并说明其调用时机。 拷贝构造函数是一种特殊的构造函数,用于创建一个新对象,其内容与另一个对象相同。它将一个已存在的对象作为参数,并使用该对象的值来初始化新创建的对象。拷贝构造函数的调用时机…...
DFS2 C++
一、指数型枚举 1、题目: 从 1∼n1∼ 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。 输入格式 输入一个整数 n。 输出格式 每行输出一种方案。 同一行内的数必须升序排列,相邻两个数用恰好 11 个空格隔开。 对于没有选任何…...
2021-08-06
yarn的简介: Yarn是facebook发布的一款取代npm的包管理工具。 yarn的特点: 速度超快。 Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。 在执行代码…...
Centos服务器Open Gauss 部署
近期很多的项目由于信创要求使用一些国产的数据库,比如OpenGauss。OpenGuass是华为高斯DB的开源版,内核还是PostgreSQL,商业版是收费的。这里记录一下是如何安装部署 的。 官方中文文档 官方下载地址 部署要求 操作系统要求 ARMÿ…...
Vue与Electron融合之道:从Web App到桌面App的华丽转身
Vue与Electron融合之道:从Web App到桌面App的华丽转身 引言Vue 与 Electron 的天然契合共享技术栈高效开发与部署用户体验升级 Vue 与 Electron 融合实战初始化项目调整Vue项目结构利用 Electron API 增强功能定制桌面应用外观构建与部署 结语 引言 Vue.js 作为一款…...
Higress 基于自定义插件访问 Redis
作者:钰诚 简介 基于 wasm 机制,Higress 提供了优秀的可扩展性,用户可以基于 Go/C/Rust 编写 wasm 插件,自定义请求处理逻辑,满足用户的个性化需求,目前插件已经支持 redis 调用,使得用户能够…...
Mysql的库函数
MySQL是一个流行的开源关系型数据库管理系统,它提供了大量的内置库函数,用于在查询时执行各种操作。这些函数可以帮助开发者在数据检索、转换和处理过程中实现更复杂的逻辑。 1 字符串函数 函数描述ASCII(s)返回字符串 s 的第一个字符的 ASCII 码。CHA…...
绿联 安装onlyoffice容器并启用Cloudreve的office在线预览与编辑功能
原文:绿联 安装onlyoffice容器并启用Cloudreve的office在线预览与编辑功能 本篇教程以配合Cloudreve扩展文档预览/编辑为目的编写,OnlyOffice的其他用途未深入研究也不做探讨,仅使用WOPI能力。 硬件要求 镜像大小:2.91Gb或更大 …...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...

