当前位置: 首页 > 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备份到移动硬盘 如果…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...