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

【C++ 】list 类

1. 标准库中的list类

list 类 的介绍:

1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代

2. list与forward_list非常相似:最主要的不同在于forward_list是单链表

3. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好,只是不支持任意位置的随机访问

a. list 的构造函数

  • list() (无参构造函数)
  • list (const list& x) (拷贝构造)
  • list (InputIterator first, InputIterator last)

( 用[first, last)区间中的元素构造list )

  • list (size_type n, const value_type& val = value_type())

( 构造的list中包含n个值为val的元素 )

注意:

list 的迭代器是双向迭代器(完成 ++ , --),可以支持传单向迭代器( 完成 ++ ) 和双向迭代器

b. list 增删查改

  • push_back (尾插)
  • push_front (头插)
  • pop_back (尾删)
  • pop_front (头删)
  • insert (在某一位置前增加新节点)

代码举例1

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(0);lt.push_back(10);lt.push_back(20);lt.push_back(30);list<int> ::iterator it = lt.begin();++it;lt.insert(it,70);it = lt.begin();while(it != lt.end()){cout << *it << endl;++it;}
}

运行结果:

  • earse (删除某一位置的节点)

代码举例2

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(0);lt.push_back(10);lt.push_back(20);lt.push_back(30);list<int> ::iterator it = lt.begin();++it;lt.erase(it);it = lt.begin();while(it != lt.end()){cout << *it << endl;++it;}
}

运行结果:

  • swap ( 交换两个list中的元素 )

代码举例3

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(10);lt.push_back(20);lt.push_back(30);list<int> llt;llt.push_back(4);llt.push_back(5);llt.push_back(6);lt.swap(llt);auto it = lt.begin();while(it != lt.end()){cout << *it << " ";++it;}cout << endl;for (auto i : llt){cout << i << " ";}
}

运行结果:

  • clear (清除有效节点,即不包括哨兵位)

c. list 容量

d. list 获取元素

e. list 迭代器

  • begin + end ( 返回第一个元素的迭代器+ 返回最后一个元素下一个位置的迭代器 )

画图分析

  • rbegin + rend ( 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置 )

注意:

反向迭代器的模拟实现和我们理解的有偏差,图上为了理解,我们可以认为rbegin是最后一个元素,rend是第一个元素的前一个位置

但是实际上,rbegin指向的位置就是end的位置,rend指向的位置就是rbegin的位置,但是在解引用时,会运算符重载 *,得到该位置的上一个位置 (详情看 list 模拟实现)

2. 迭代器失效 

list 迭代器类似一个指针,指向节点的地址 (具体详情看 list 的模拟实现)

所以在发生 erase 的时候容易造成迭代器失效(即野指针)

3. list 类的模拟实现

代码

namespace lhy
{template<class T>
struct ListNode
{
public:ListNode* prev;ListNode* next;T val;ListNode(const T& t = T()){prev = next = nullptr;val = t;}
};
template<class T,class Ref,class Ptr>
class list_iterator
{
public:typedef list_iterator<T,Ref,Ptr>  self;list_iterator(ListNode<T>* n):_node(n){}Ptr operator->(){return &_node->val;}Ref operator*(){return _node->val;}self& operator++(){_node = _node->next;return *this;}self operator++(int){self tmp = *this;_node = _node->next;return tmp;}self& operator--(){_node = _node->prev;return *this;}self operator--(int){self tmp = *this;_node = _node->prev;return tmp;}bool operator!=(const list_iterator& t){return _node != t._node;}bool operator==(const list_iterator& t){return _node == t._node;}ListNode<T>* _node;
};template<class iterator,class Ref,class Ptr>class list_converse_iterator{private:iterator com;public:typedef list_converse_iterator  self;list_converse_iterator(iterator& it):com(it){}Ptr operator->(){return &(*com);}Ref operator*(){iterator tmp = com;--tmp;return *tmp;}self& operator++(){--com;return *this;}self operator++(int){self tmp = *this;--*this;return tmp;}self& operator--(){++com;return *this;}self operator--(int){self tmp = *this;++*this;return tmp;}bool operator!=(const self& t){return com != t.com;}bool operator==(const self& t){return com == t.com;}};template<class T>class List{public:typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, const T&, const T*>  const_iterator;typedef list_converse_iterator<iterator, T&, T*>  converse_iterator;typedef list_converse_iterator<iterator, const T&,const T*>  const_converse_iterator;List(){node = new ListNode<T>;node->next = node;node->prev = node;}iterator begin(){return iterator(node->next);}const const_iterator begin() const{return const_iterator(node->next);}iterator end(){return iterator(node);}const const_iterator end() const{return const_iterator(node);}converse_iterator rbegin(){return converse_iterator(end());}const_converse_iterator rbegin() const{return const_converse_iterator(end());}converse_iterator rend(){return converse_iterator(begin());}const_converse_iterator rend(){return const_converse_iterator(begin());}void push_back(const T& val){ListNode<T>* ptail = node->prev;ListNode<T>* newnode = new ListNode<T>(val);ptail->next = newnode;newnode->next = node;	newnode->prev = ptail;node->prev = newnode;}void push_front(const T& x){insert(begin(), x);}void insert(iterator pos,const T &x){ListNode<T>* cur = pos._node;ListNode<T>* newnode = new ListNode<T>(x);newnode->next = cur;newnode->prev = cur->prev;cur->prev->next = newnode;cur->prev = newnode;}void earse(iterator pos){ListNode<T>* cur = pos._node;assert(cur != node);ListNode<T>* _prev = cur->prev;ListNode<T>* _next = cur->next;_prev->next = _next;_next->prev = _prev;delete cur;}
private:ListNode<T>* node;
};
}

list 迭代器的实现 

单看这一个类的实现,可能会疑惑,已经有一个 List 类了,为什么还要加一个 list_iterator 类,并且很容易发现,两个类的成员变量是一样的

如:list<int> :: iterator it;

我们希望 *it 得到的是T类型的变量(这里是int 类型)

而 it++ 得到的是下一个节点的地址

如果是只有 List 类,无法实现

因为如果 typedef ListNode* iterator

那么 *it 的类型就是 ListNode;

it++ 也不是下一个结点的地址(这是链表,开辟的空间不是连续的)

所以这里的 list_iterator 类是为了运算符重载 *和++

代码注意事项

可以和下面的对应


 

注意:

const iterator 修饰的是 (ListNode<T>*),即指针不可以更改,但是指针所指向的内容可以更改

const_iterator 修饰的是 const ListNode<T>* ,即指针所指向的内容不可更改

注意:

对于这个运算符重载,实际写的时候只要写一个 -> 就行,编译器简化两个 ->

模板第一个传的是 正向迭代器,利用正向迭代器来实现反向迭代器的功能

这里 运算符重载* 让正向迭代器--再解引用,是为了得到 原先T 类型的数据的前一个数据,原因如下:

这里传递是 end() ,但是 对应的数据不是我们想要的

才会在解引用得到前一个数据的值

相关文章:

【C++ 】list 类

1. 标准库中的list类 list 类 的介绍&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代 2. list与forward_list非常相似&#xff1a;最主要的不同在于forward_list是单链表 3. 与其他的序列式容器相比(a…...

Linux下的多线程编程:原理、工具及应用(2)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Flower of Life—陽花 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶️ ☰ …...

微信小程序-webview分享

项目背景 最近有个讨论区项目需要补充分享功能&#xff0c;希望可以支持在微信小程序进行分享&#xff0c;讨论区是基于react的h5项目&#xff0c;在小程序中是使用we-view进行承载的 可行性 目标是在打开web-view的页面进行分享&#xff0c;那就需要涉及h5和小程序的通讯问…...

webpack5零基础入门-8清空前次打包文件与处理图标字体资源

1.配置output中的clean属性为true output: {/**文件输出路径 绝对路径*///__dirname 表示当前文件的文件夹目录path: path.resolve(__dirname, dist),//所有文件的输出目录/**文件名 */filename: static/js/dist.js,//入口文件输出文件名clean: true,//在打包前将path整个目录内…...

中国首个基于区块链的分布式算力网络上线

随着美国人工智能公司OpenAI近期发布的Sora视频模型&#xff0c;全球对高性能算力的需求突破了历史新高。Sora的创新在于它能够以超长生成时间、多角度镜头捕捉&#xff0c;理解物理世界的能力&#xff0c;这不仅是技术的一大突破&#xff0c;更是对算力需求的一大挑战。在这样…...

cesiumlab中shp转3dtiles白模效果一

安装cesiumlab 如果没有安装cesiumlab&#xff0c;去官网下载安装一个即可 http://www.cesiumlab.com/cesiumlab.html 效果 步骤 1、准备shp面数据 2、打开cesiumlab软件转换 选择shp面数据 设置高度&#xff0c;如果shp面中有高度字段&#xff0c;可以用高度字段&#xff…...

照片生成数字人技术重塑虚拟主播生态

随着数字技术的飞速发展&#xff0c;虚拟主播已成为现代传媒领域的一股新势力。然而&#xff0c;传统虚拟主播形象制作周期长、成本高的问题&#xff0c;限制了其在多个场景下的广泛应用。美摄科技&#xff0c;作为业界领先的数字内容创新者&#xff0c;针对这一痛点&#xff0…...

前端和后端权限控制【笔记】

前端权限设置【笔记】 前言版权推荐前端权限设置需求效果实现资源 后端权限控制1.给所有前端请求都携带token2.添加拦截器3.配置到WebMvcConfiguration4.更多的权限验证 最后 前言 2024-3-15 18:27:26 以下内容源自《【笔记】》 仅供学习交流使用 版权 禁止其他平台发布时删…...

老电脑装什么系统流畅

对于一些老旧电脑来说&#xff0c;重装系统是提升电脑性能的最佳选择。那么&#xff0c;老电脑装什么系统流畅呢&#xff1f;推荐Windows 7系统&#xff0c;它对硬件的需求相对较低。配置较低的电脑运行Windows 7可以更好地利用系统资源&#xff0c;提高电脑的运行速度和响应能…...

厉害了!机器视觉在农业中的应用

机器视觉是一门涉及模式识别、神经生物学、计算机科学、人工智能、图像处理、心理物理学等诸多领域的交叉学科。主要是通过计算机对人类某些视觉方面的智能行为的模拟和再现,再处理并理解从客观事物的图像中提取到的信息,最终达到在实际检测和控制中应用的目的。近年来,随着…...

简述从浏览器发出请求到数据返回的全过程

下面是我结合经验概述的从浏览器发出请求到数据返回的全过程。 一、用户请求 1、用户在浏览器输入URL&#xff0c;或通过功能发起请求&#xff1b; 2、解析URL&#xff0c;提取协议(http,https等)&#xff0c;IP&#xff0c;端口&#xff0c;域名&#xff0c;路径等信息&#x…...

MongoDB性能最佳实践:硬件和操作系统配置

欢迎阅读有关MongoDB性能最佳实践的系列博文。在往期文章中&#xff0c;我们已经讨论过查询模式和性能分析、事务和读/写关注等实现大规模性能的关键考虑因素。在本篇文章中&#xff0c;我们将讨论硬件和操作系统配置。 如果您在阿里云上部署MongoDB&#xff0c;那么阿里云会为…...

mysql查询条件包含IS NULL、IS NOT NULL、!=、like %* 、like %*%,不能使用索引查询,只能使用全表扫描,是真的吗???

不知道是啥原因也不知道啥时候, 江湖上流传着这么一个说法 mysql查询条件包含IS NULL、IS NOT NULL、!、like %* 、like %*%,不能使用索引查询&#xff0c;只能使用全表扫描。 刚入行时我也是这么认为的&#xff0c;还奉为真理&#xff01; 但是时间工作中你会发现还是走索引…...

使用IDEA2023创建传统的JavaWeb项目并运行与调试

日期:2024-0312 作者:dusuanyun 文档环境说明: OS:Deepin 20.9(Linux) JDK: OpenJDK21 Tomcat:10.1.19 IDEA: 2023.3.4 (Ultimate Edition) 本文档默认已经安装JDK及环境变量的配置。 关键词…...

【快捷部署】002_Flink(1.17.2)

&#x1f4e3;【快捷部署系列】002期信息 编号选型版本操作系统部署形式部署模式002Flink1.17.2CentOS 7.Xtgz包单机 &#x1f449; 演示视频 Flink一键安装&#xff08;本地模式&#xff09; install-flink.sh 脚本内容 #!/bin/bash ####变量 ###执行脚本的当前目录 mydir$…...

智慧公厕建设,助力打造宜居、韧性、可持续的智慧城市

公共厕所作为智慧城市的重要组成部分&#xff0c;对于城市的高质量发展起着至关重要的作用。智慧公厕建设旨在通过全面监测、控制和管理公共厕所&#xff0c;实现多方面功能&#xff0c;包括公共厕所环境监测与调控、厕位占用监测与引导、消耗品监测与缺失提示、安全防范与管理…...

[Django 0-1] Core.Cache模块

Caching 源码分析 Django 的 cache 缓存机制&#xff0c;包含了一些代理设计模式(代理了但没完全代理&#xff0c;多此一举)。 通过实现一个CacheHandler的manager类&#xff0c;来实现多缓存后端的统一管理和调用&#xff0c;避免到处实例使用。 缓存的目的 缓存的目的就是…...

spy分析文件另存为弹框【selenium】

有时需要下载多个文件&#xff0c;但是不想保存在同一个目录下&#xff0c;需要做两步 selenium设置浏览器默认下载路径&#xff0c;这个路径需要是个不存在的路径操作文件另存为弹框 文章目录 selenium设置浏览器默认下载路径操作文件另存为弹框 selenium设置浏览器默认下载路…...

分布式与集群,二者区别是什么?

&#x1f413;分布式 分布式系统是由多个独立的计算机节点组成的系统&#xff0c;这些节点通过网络协作完成任务。每个节点都有自己的独立计算能力和存储能力&#xff0c;可以独立运行。分布式系统的目标是提高系统的可靠性、可扩展性和性能。 分布式服务包含的技术和理论 负…...

(done) 什么是词嵌入技术?word embedding ?(这里没有介绍词嵌入算法)(没有提到嵌入矩阵如何得到)

参考视频&#xff1a;https://www.bilibili.com/video/BV1sw411S7i1/?spm_id_from333.788&vd_source7a1a0bc74158c6993c7355c5490fc600 词嵌入&#xff08;word embedding&#xff09;&#xff1a;把词汇表中的词或短语 -------- 映射 ----> 固定长度向量 我们可以把 …...

C++静态成员函数和非静态成员函数之间的相互调用

C静态成员函数和非静态成员函数之间的相互调用 一直对C静态成员函数和非静态成员函数之间的相互调用记不住&#xff0c;都是死记硬背&#xff0c;今天突然醍醐灌顶&#xff1b; 1、静态成员函数不能调用非静态成员函数&#xff0c;因为静态成员函数属于类&#xff0c;没有this…...

最好用的流程编辑器bpmn-js系列之基本使用

BPMN&#xff08;Business Process Modeling Notation&#xff09;是由业务流程管理倡议组织BPMI&#xff08;The Business Process Management Initiative&#xff09;开发的一套标准的业务流程建模符号规范。其目的是为用户提供一套容易理解的标准符号&#xff0c;这些符号作…...

Singularity(八)| conda实战

Singularity&#xff08;八&#xff09;| conda实战 8.1 conda 和容器的区别 Conda和容器技术&#xff08;如Docker&#xff09;都是现代软件开发和数据科学中常用的工具&#xff0c;用于解决环境依赖和应用部署的问题。尽管它们有着相似的目标&#xff0c;即确保应用可以在不…...

elementui el-select组件多选设置初始值无法修改问题

elementui el-select组件多选设置初始值无法修改问题 对list直接赋值后点击修改select框&#xff0c;此时数据已改变但显示无变化。 <el-select v-model"form.optrList" multiple placeholder"请选择"><el-optionv-for"item in list":k…...

电脑自动关机后文件夹不见了怎么办?别急,找回方法在这里

在使用电脑的过程中&#xff0c;我们都可能会遇到一些令人头疼的问题&#xff0c;其中之一就是电脑突然自动关机后&#xff0c;发现重要的文件夹不见了。这种情况可能会让你感到焦虑和困惑&#xff0c;因为失去的数据可能涉及到工作、学习或生活中的各个方面。不过&#xff0c;…...

tcp/ip协议2实现的插图,数据结构8 (30 - 32章)

(201) 201 三十0 中断优先级补充 (202) 202 三十1 TCP的用户需求 函tcp_usrreq一 (203) 203 三十2 TCP的用户需求 函tcp_usrreq二 (204) 204 三十3 TCP的用户需求 函tcp_usrreq三 (205) 205 三十4 TCP的用户需求 函tcp_usrreq四 (206) 206 三十5 TCP的用户需求 函tcp_usrreq五 …...

挑战杯 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …...

【数据结构】顺序表的定义及实现方式

文章目录 顺序表的定义顺序表的实现静态分配动态分配动态申请内存空间&#xff0c;动态释放内存空间&#xff08;malloc&#xff0c;free&#xff09; 顺序表的特点总结 顺序表的定义 顺序表也就是用顺序存储的方式实现线性表。 顺序存储。把逻辑上相邻的元素存储在物理位置上…...

R语言数据挖掘-关联规则挖掘(1)

一、分析目的和数据集描述 要分析的数据是美国一区域的保险费支出的历史数据。保险费用数据表的每列分别为年龄、性别、体重指数、孩子数量、是否吸烟、所在区域、保险收费。 本文的主要目的是分析在年龄、性别、体重指数、孩子数量、是否吸烟、所在区域中这些因素中&#xf…...

【ansible】ansible的介绍和安装

前言运维自动化 云计算核心职能 搭建平台架构 日常运营保障 性能效率优化 相关工具 代码管理&#xff08;SCM&#xff09;&#xff1a;GitHub、GitLab、BitBucket、SubVersion 构建工具&#xff1a;maven、Ant、Gradle 自动部署&#xff1a;Capistrano、CodeDeploy 持续…...