当前位置: 首页 > news >正文

C++入门篇9---list

list是带头双向循环链表

一、list的相关接口及其功能

1. 构造函数

函数声明功能说明
list(size_type n,const value_type& val=value_type())构造的list中包含n个值为val的元素
list()构造空的list
list(const list& x)拷贝构造
list(InputIterator first, InputIterator last)[fiirst,last)区间的元素构造list
void test1()
{list<int> v;list<int> v1(5,2);list<int> v2(v1);list<int> v3(v1.begin(),v1.end());for (auto x : v)cout << x << " ";cout << endl;for (auto x : v1)cout << x << " ";cout << endl;for (auto x : v2)cout << x << " ";cout << endl;for (auto x : v3)cout << x << " ";cout << endl;}

 2.list的迭代器

函数名称功能名称
begin()+end()获取第一个数据位置的iterator/const_iterator,获取最后一个数据的下一个位置的iterator/const_iterator
rbegin()+rend()获取第一个数据位置的reverse_iterator/const_reverse_iterator,获取最后一个数据的下一位置的reverse_iterator/const_reverse_iterator

 

void test2()
{list<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);list<int>::iterator it = v.begin();//注意如果写类型名,那么一定要写正确,如加不加reverse、const一定要写对//如果不想写这么长的类型,可以写auto自动类型推导while (it != v.end()){cout << *it << " ";it++;}cout << endl;list<int>::reverse_iterator it1 = v.rbegin();while (it1 != v.rend()){cout << *it1 << " ";it1++;}cout << endl;
}

3.list的capacity

函数声明功能介绍
empty()检测list是否为空
size()返回list中有效结点的个数

 4.获取首尾元素

函数声明功能介绍
front返回list的第一个节点中值的引用
back返回list的最后一个结点中值的引用

5.list的修改

函数名称功能介绍
push_front在list首元素前插入值为val的值
pop_front删除list中第一个元素
push_back在list尾部插入值为val的值
pop_back删除list中的最后一个元素
insert在list中pos位置插入值为val的元素
erase删除list中pos位置的元素
swap交换两个list中的元素
clear清空list中的有效元素
void test3()
{list<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_front(1);v.push_front(2);v.push_front(3);v.push_front(4);for (auto x : v)cout << x << " ";cout << endl;v.pop_back();v.pop_front();for (auto x : v)cout << x << " ";cout << endl;v.insert(v.begin(),10);for (auto x : v)cout << x << " ";cout << endl;v.erase(v.begin());for (auto x : v)cout << x << " ";cout << endl;
}

 6.list迭代器失效问题(重点

在讲vector的博客中,我也提到了迭代器失效问题,那么问个问题,list的迭代器失效和vector的迭代器失效一样吗?为什么?

这里先解释一下什么是迭代器,估计有很多人对这个名词还不是很了解,其实所谓的迭代器从作用上来说就是访问遍历容器的工具,它将所有容器的访问遍历方式进行了统一(vector,list,set等等容器的迭代器使用几乎一摸一样都是begin(),end(),++/--等操作),封闭了底层的细节,简化了我们对容器的使用,对于初学者来说,这玩意tm的太神了,但是如果我们了解它的底层实现,我们就会发现,迭代器不过是一层封装,底层还是数据结构那一套,如list链表,迭代器的++,本质还是指针的变化。

(容器的底层实现还是要了解一些,能够帮助我们更好的认识和使用容器,可以看看我写过的一些模拟实现,如果有需要注释或者详解,请在评论区留言,如果需求多,我会单独出一篇博客讲解一下里面的一些重点内容)

好,下面回归正题,如果你数据结构学的还不错并且知道vector的迭代器失效是扩容引起的,那么这个问题不难回答,因为链表的增查改不会影响一个结点的位置,除了删除操作,所以list的迭代器失效仅仅只有在删除list结点时才会出现,并且只有那个被删除结点的迭代器会失效,其他的不受影响

二、模拟实现list的基本功能

namespace zjs
{template <class T>struct list_node {T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& data = T()):_data(data),_next(nullptr),_prev(nullptr){}};//重点template <class T, class Ref, class Ptr >struct __list_iterator {typedef list_node<T> Node;typedef __list_iterator self;Node* node;__list_iterator(Node* x):node(x){}self& operator++(){node = node->_next;return *this;}self& operator--(){node = node->_prev;return *this;}self operator++(int){self tmp(*this);node = node->_next;return tmp;}self operator--(int){self tmp(*this);node = node->_prev;return tmp;}Ref operator*(){return node->_data;}bool operator==(const self& It) const{return node == It.node;}bool operator!=(const self& It) const{return node != It.node;}Ptr operator->(){return &node->_data;}};/*template <class T>struct __list_const_iterator {typedef list_node<T> Node;typedef __list_const_iterator self;Node* node;__list_const_iterator(Node* x):node(x){}self& operator++(){node = node->_next;return *this;}self& operator--(){node = node->_prev;return *this;}self operator++(int){self tmp(*this);node = node->_next;return tmp;}self operator--(int){self tmp(*this);node = node->_prev;return tmp;}const T& operator*() {return node->_data;}const T* operator->(){return &node->_data;}bool operator==(const self& It){return node == It.node;}bool operator!=(const self& It){return node != It.node;}};*/template <class T>class list{public:typedef list_node<T> Node;typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T,const T&,const T*> const_iterator;//typedef __list_const_iterator<T> const_iterator;void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){_size = 0;empty_init();}void clear(){iterator it = begin();while (it!=end()){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& tmp):_head(nullptr),_size(0){empty_init();for (auto& x : tmp){push_back(x);}}void swap(list& tmp){std::swap(_head, tmp._head);std::swap(_size, tmp._size);}list<T>& operator=(list<T> tmp){swap(tmp);return *this;}const_iterator begin() const{return _head->_next;}iterator begin(){//return iterator(_head->_next);return _head->_next;}const_iterator end() const{//return iterator(_head);return _head;}iterator end(){//return iterator(_head);return _head;}void push_back(const T& x){//Node* tail = _head->_prev;//Node* newnode = new Node(x);//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}iterator insert(iterator pos, const T& x){Node* cur = pos.node;Node* pre = cur->_prev;Node* newnode = new Node(x);pre->_next = newnode;newnode->_prev = pre;newnode->_next = cur;cur->_prev = newnode;_size++;return newnode;}void pop_back(){erase(--end());}void pop_front(){erase(begin());}iterator erase(iterator pos){Node* cur = pos.node;Node* pre = cur->_prev;Node* next = cur->_next;pre->_next = next;next->_prev = pre;delete cur;_size--;return next;}size_t size() const{return _size;}private:Node* _head;size_t _size;};//模板的一些应用,typename的用法//这里只能用typedef,用来告诉编辑器const_iterator是一个类型名,而不是一个静态变量//因为编辑器在编译阶段要判断有没有语法错误,而list<T>没有实例化,就无法在里面//查找const_iterator,而如果它是静态变量很显然这是个语法错误,//所以这里要加上typename告诉编辑器这是个类型名,等到实例化之后再去里面找template<typename T>void print_list(const list<T>& s){typename list<T>::const_iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;}template<typename container>void print_container(const container& s){typename container::const_iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;}}

相关文章:

C++入门篇9---list

list是带头双向循环链表 一、list的相关接口及其功能 1. 构造函数 函数声明功能说明list(size_type n,const value_type& valvalue_type())构造的list中包含n个值为val的元素list()构造空的listlist(const list& x)拷贝构造list(InputIterator first, InputIterator…...

STM32基于CubeIDE和HAL库 基础入门学习笔记:物联网项目开发流程和思路

文章目录&#xff1a; 第一部分&#xff1a;项目开始前的计划与准备 1.项目策划和开发规范 1.1 项目要求文档 1.2 技术实现文档 1.3 开发规范 2.创建项目工程与日志 第二部分&#xff1a;调通硬件电路与驱动程序 第三部分&#xff1a;编写最基础的应用程序 第四部分&…...

Hive on Spark (1)

spark中executor和driver分别有什么作用&#xff1f; Spark中Executor 在 Apache Spark 中&#xff0c;Executor 是分布式计算框架中的一个关键组件&#xff0c;用于在集群中执行具体的计算任务。每个 Executor 都在独立的 JVM 进程中运行&#xff0c;可以在集群的多台机器上…...

PostgreSQL基本操作总结

安装按PostgreSQL数据库后&#xff0c;会默认创建用户postgres和数据库postgres&#xff0c;这个用户是超级用户&#xff0c;权限最高&#xff0c;可以创建其他用户和权限&#xff0c;在实际开发过程中&#xff0c;会新创建用户和业务数据库&#xff0c;本文主要介绍用户权限和…...

Jakarta 的 Servlet 下BeanUtils的日期处理 和JSTL 的使用

jsp优于性能等问题已经不被spring boot等支持&#xff0c;如果想使用jsp和jstl标签库需要引入一下依赖。 <!-- 用jakarta.servlet.jsp.jstl&#xff0c;用org.glassfish.web--><dependency><groupId>jakarta.servlet.jsp.jstl</groupId><art…...

聚焦电力行业CentOS迁移,麒麟信安受邀参加第六届电力信息通信新技术大会暨数字化发展论坛并发表主题演讲

为加快推进“双碳”目标下的新型能源体系和新型电力系统建设&#xff0c;深化新一代数字技术与电力业务的融合发展&#xff0c;促进电力行业关键技术自主创新、安全可控&#xff0c;助力电力企业数字化转型升级和高质量发展&#xff0c;2023年8月9-11日&#xff0c;第六届电力信…...

华为OD真题--分月饼--带答案

1. 华为OD机考题 答案 2023华为OD统一考试&#xff08;AB卷&#xff09;题库清单-带答案&#xff08;持续更新&#xff09; 2023年华为OD真题机考题库大全-带答案&#xff08;持续更新&#xff09; 2. 面试题 一手真实java面试题&#xff1a;2023年各大公司java面试真题汇总--…...

帆软大屏2.0企业制作

&#xfffc; 数字化观点中心 / 当前页 如何从0-1制作数据大屏&#xff0c;我用大白话给你解释清楚了 文 | 商业智能BI相关文章 阅读次数&#xff1a;18,192 次浏览 2023-06-08 11:51:49 好莱坞大片《摩天营救》中有这么一个场景&#xff1a; &#xfffc; 你可以看见反派大b…...

【学习笔记之opcua】使用Python获取opcua数据

Python与OPC UA的应用 示例代码 将代码放入spyder中运行后&#xff0c;出现下面这个错误 没有‘opcua’&#xff0c;那我们就下载pip install opcua 之后出现下面这个错误 问问题大不&#xff0c;安装语句写错了 正经安装语句是 !pip install opcua 读取opcua协议数据测试 …...

apache doris和StarRocks的区别

记录一下最新要用到2个新数据库的区别 Apache Doris是一个分布式的列式存储系统&#xff0c;它的设计目标是提供大规模数据处理的可靠性和高性能。Doris采用了集群方式&#xff0c;通过将数据分布在多个机器上进行处理来提高性能&#xff0c;并提供了SQL查询接口方便用户使用。…...

文心一言最新重磅发布!

8月16日&#xff0c;由深度学习技术及应用国家工程研究中心主办的WAVE SUMMIT深度学习开发者大会2023举办。百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰以《大语言模型为通用人工智能带来曙光》为题&#xff0c;阐述了大语言模型具备理解、生成、逻辑、记忆…...

css整体使用

文章目录 html与csshtml、css与排版响应式与自适应布局自适应布局响应式布局 css规则class、id、以及默认的标签名的优先级 css书写位置flex整体逻辑 bootstrap资源 html与css html负责网页功能&#xff0c;css负责网页美化&#xff1b;浏览器本身有一套默认的css样式&#xf…...

LeetCode1578. 使绳子变成彩色的最短时间

思路 拆除成本 全部拆除 - 最大的不拆除在统计成本的同时&#xff0c;维持一个成本的最大值 代码 class Solution {public int minCost(String colors, int[] neededTime) {int res 0;int i 0;int len colors.length();while (i < len) {int max -1;int sum 0;char…...

如何在机器学习中实现分类?

机器学习和统计学中的分类是一种监督学习方法,其中计算机程序从给定的数据中学习并进行新的观察或分类。在本文中,我们将详细了解机器学习中的分类。 本博客涵盖以下主题: 目录 什么是机器学习中的分类? 机器学习中的分类术语 分类算法...

华为网络篇 RIP的负载均衡-29

难度2复杂度2 目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 RIP是使用跳数&#xff08;经过路由的数量&#xff09;作为metric值的&#xff0c;当网络上存在去往目标的路由有两条以上都是相同metric时&#xff0c;就出现了流量负载均衡。…...

前端面试的性能优化部分(10)每天10个小知识点

目录 系列文章目录前端面试的性能优化部分&#xff08;1&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;2&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;3&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;4&#xff09;每天…...

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 目录 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 程序设计 完整源码和数据获取方式&#xff1a; …...

maven -pl -am -amd

maven常见命令之 -pl -am -amd 昨天maven的deploy任务需要只选择单个模块并且把它依赖的模块一起打包&#xff0c;第一时间便想到了-pl参数&#xff0c;然后就开始处理&#xff0c;但是因为之前只看了一下命令的介绍&#xff0c;竟然花了近半小时才完全跑通&#xff0c;故记录…...

高效解决Anaconda Prompt报错Did not find VSINSTALLDIR这类问题

文章目录 回忆问题解决问题step1step2 回忆问题 类似于划红线部分然后还有很多行的报错信息&#xff0c;最后一行肯定是红色划线部分 解决问题 step1 找到 D:\Anaconda\envs\pytorch\etc\conda\activate.d在这个文件夹内会有两个文件&#xff0c;删除 vs2017_compiler_v…...

将iPhone备份到移动硬盘

文章目录 将iPhone备份到移动硬盘如何在 MacOS 上查找当前备份如何在 MacOS 上查找当前备份如何将 iPhone 备份移至外部硬盘如何永久更改 Mac系统 保存 iPhone 备份的位置更新 Mac 上的权限更改 iPhone 备份位置如何验证新的 iPhone 备份已经生效?将iPhone备份到移动硬盘 如果…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...