c++:list

1.list的使用

1.1构造

1.2迭代器遍历

(1)迭代器是算法和容器链接起来的桥梁

容器就是链表,顺序表等数据结构,他们有各自的特点,所以底层结构是不同的。在不用迭代器的前提下,如果我们的算法要作用在容器上面,不可避免的需要获取底层结构,这不仅会增加耦合度,而且也不利于算法库的实现。所以我们创建一个迭代器,将底层结构的访问方式封装成迭代器,直接利用迭代器去访问容器。

有两个好处,

其一,我们不用根据各种各样的容器去一直创造新的算法兼容,保证了算法库的可维护性

其二,我们的访问更加简单了,都用迭代器访问,不需要对各种容器的底层有很多了解

1.3首尾元素访问

1.4插入数据

第一行表示在it迭代器的位置插入一个2

第二行表示在it位置插入三个1

第三行创建了有两个元素值为10的链表,然后第四行把test从头到尾的节点值都插入到了it位置

1.5删除数据

还有一个删除函数:remove

他会删除所有指定值的元素

这里我们删除10这个值之前second里面有两个10

我们进行remove(10)后,list里面的10都被删除了。

1.6交换链表

1.7清除所有有效数据

1.8排序

list自带的排序效率很低

甚至我们先把数据拷贝给vector,用vector排完序之后再给回list,此时我们list自己排序花的时间比拷贝到vector排完序再拷贝回来还要慢。

1.9splice(剪贴)

splice的作用是把list中某一段迭代器区间的内容移动到pos迭代器的位置的前面,就像剪切一样

一共有三种用法

第一种:把整个list剪切到pos迭代器位置

这里我们看到一开始second是有四个节点,经过整个second的剪切, second变成空链表,而first则具有了second的四个节点

第二种:把list的it位置节点剪切到pos迭代器位置

这里我们看到,成功的把second的第一个节点剪切到了first上

第三种:把list中一段迭代器区间的内容剪切到pos迭代器位置

这里我们把second的后面三个节点都剪切到了first中

2.list的模拟实现

2.1节点

2.1.1结构

由于我们实现的是双向带头循环链表,所以我们节点中需要存有前一个和下一个节点的地址,以及最基本的节点的值。

注意:因为我们实现的是模板的链表节点,所以才要写成list_node<T>.

疑问:我们不是不希望暴露底层结构吗?为什么这里用struct?

首先,我们后面的list需要频繁使用到节点内的指针等

其次,因为每个编译器内部实现的时候命名没有统一,所以我们就算想访问也是很难的

2.1.2构造函数

这里我们使用匿名对象来给到缺省值,对于自定义类型和内置类型都可以有效

内置类型:

自定义类型:

自定义类型会调用对应的构造函数

2.2迭代器

2.2.1结构

这里的迭代器底层是指向链表节点的指针,但是迭代器的类型实际上是一个自定义类型

让自定义类型充当迭代器的原因:对于链式结构,内置类型指针无法实现++移动到下一个元素的迭代器位置,所以我们需要把它封装成自定义类型,通过运算符重载实现++移动到下一个元素迭代器位置。

简单来说,原生指针指向地址的功能没问题,但是移动到下一个元素的内置元素运算符逻辑无法满足链式结构的遍历,所以需要我们把迭代器类型设置为自定义类型,通过自定义类型的运算符重载实现链式遍历。

2.2.2构造函数

因为结构中只有一个指向链表节点的指针,所以这里我们只要用node初始化即可

2.2.3运算符重载

(1)解引用

1.非const迭代器版本

解引用就是为了访问节点的值,所以我们直接返回m_date

2.const迭代器版本

const T& operator*()
{
  return node->m_date;
}

这里返回的是const就保证了指向的内容不可改变,注意我们不可以在函数后面加const,如果那样加就表示迭代器本身不可改变了

(2)++与--

++是为了我们可以访问到下一个节点的位置,而下一个节点的位置我们可以通过

node->next访问,把node更新一下就行

(3)!=

判断迭代器指向的位置是否相等只要判断他们的node就行

(4)==

(5)->

当我们的数据类型是自定义类型的时候,我们有两种方法访问该自定义类型内的值

第一种:解引用然后用.访问

第二种:->再用->访问(场景比较固定)

比如说我们的list中存的是A类型对象,那么我们要访问到a1就需要先访问节点中的m_date(A类型数据),然后再访问a1或a2.

(1)非const版本

我们返回的是A类型的指针,然后再->访问a1或者a2。

为了保证可读性,我们不会用两个->去表示,而是直接缩略成一个->

(2)const版本

2.2.4const与非const迭代器合并

我们首先要添加两个模板参数,Ref和Ptr。

Ref表示引用(&),Ptr表示指针(*)

因为const和非const只有两个方法存在区别,所以我们把这两个方法的返回值设置为模板参数

然后我们在list中typedef即可

2.3链表

2.3.1结构

因为我们是双向链表,所以只需要知道头结点地址即可

2.3.2构造函数与析构函数

构造函数

我们的目标是构建一个节点,且该节点自成循环

拷贝构造

为了方便调用构造函数空初始化的功能,我们单独写一个empty_init方法,并调用他来为l2初始化

我们先给l2创建一个头结点初始化,然后复用push_back插入数据即可

析构函数

我们首先要写一个方法用来删除链表的所有有效节点,然后再释放list的哨兵节点

2.3.3尾插

第一步:根据传的值创建节点

第二步:调整节点指向

2.3.4 begin与end

因为头结点是不存储有效数据的,所以begin是head的下一个节点

而end是最后一个有效节点的下一个节点,所以是m_head

这个就是const版本的begin和end

2.3.5insert

第一步:记录前一个节点和下一个节点,并创建出cur节点

第二步:修改指向关系

注意:这里不存在扩容,所以也就没有迭代器失效的问题,我们的it仍然是有效的

2.3.6erase 

注意:

(1)it迭代器会失效,因为这个位置节点被删除了,空间也释放了

(2)为了方便后续的使用,我们需要返回删除后顶替上原本节点的迭代器

2.3.7赋值重载

因为传参的时候就调用了一次拷贝构造,所以l1就是被拷贝链表的深拷贝,把l1和*this交换后,调用赋值符号的对象就相当于完成了深拷贝。且由于l1是临时变量,所以他会调用析构函数释放掉,而调用赋值的对象则不会。

2.3.8改进结构

因为我们对容器的操作经常涉及size的获取,所以我们要写一个size方法。

但是对于链表这个结构,要获取size还要我们遍历一次链表,效率太低下了。于是我们可以在list的结构中加上m_size,并在构造函数和insert,erase这种设计节点数变化的方法中更新size的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964635.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1&#xff1a;如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」&#xff0c;deepseek便爆火 爆火以后便应了“人红是非多”那句话&#xff0c;不但遭受各种大规模攻击&#xff0c;即便…

游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

[权限提升] Windows 提权 维持 — 系统错误配置提权 - 注册表权限配置错误提权

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;注册表权限配置错误提权原理 通常 Windows 中的服务都是以 System 权限运行的&#xff0c;而 Windows 的服务程序的启动路径又是存放在注册表中的&#xff0c;若注册表配置不…

牛客周赛 Round 79

题目目录 A 小红的合数寻找解题思路参考代码 B 小红的小球染色解题思路参考代码 C 小红的二叉树解题思路参考代码 D 小红的“质数”寻找解题思路参考代码 E 小红的好排列解题思路参考代码 F 小红的小球染色期望解题思路参考代码 A 小红的合数寻找 \hspace{15pt} 小红拿到了一个…

Zookeeper入门部署(单点与集群)

本篇文章基于docker方式部署zookeeper集群&#xff0c;请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长&#xf…

【MySQL】MySQL经典面试题深度解析

文章目录 一、MySQL与C的深度结合1.1 为什么C项目需要MySQL&#xff1f;1.2 典型应用场景 二、基础概念面试题精讲2.1 存储引擎对比2.2 索引原理 三、C专项面试题解析3.1 连接池实现3.2 预处理语句3.3 批量操作优化 四、高级应用面试题剖析4.1 事务隔离级别4.2 锁机制详解4.3 查…

w190工作流程管理系统设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

网络安全学习 day5

状态检测和会话技术 状态检测以 “ 数据流量 ” 为单位来对报文进行检测和转发。即对一条流量的第一个报文进行包过滤规 则检查&#xff0c;并将判断结果作为这条流量的 “ 状态 ” 记录下来 。对于该条流量的后续报文&#xff0c;直接根据这个 “ 状态 ”来判断是否转发还是…

4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)

文章目录 前言一、Ajax技术&#xff08;从服务端获取数据&#xff0c;发送各种请求&#xff09;0 接口文档管理&#xff1a;使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例&#xff08;几年前的早期用法&#xff09; 二、 Axios技术(对原…

Node.js与嵌入式开发:打破界限的创新结合

文章目录 一、Node.js的本质与核心优势1.1 什么是Node.js?1.2 嵌入式开发的范式转变二、Node.js与嵌入式结合的四大技术路径2.1 硬件交互层2.2 物联网协议栈2.3 边缘计算架构2.4 轻量化运行时方案三、实战案例:智能农业监测系统3.1 硬件配置3.2 软件架构3.3 核心代码片段四、…

51c视觉~CV~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/13241694 一、CV创建自定义图像滤镜 热图滤镜 这组滤镜提供了各种不同的艺术和风格化光学图像捕捉方法。例如&#xff0c;热滤镜会将图像转换为“热图”&#xff0c;而卡通滤镜则提供生动的图像&#xff0c;这些图像看起来…

OPENPPP2 —— VMUX_NET 多路复用原理剖析

在阅读本文之前&#xff0c;必先了解以下几个概念&#xff1a; 1、MUX&#xff08;Multiplexer&#xff09;&#xff1a;合并多个信号到单一通道。 2、DEMUX&#xff08;Demultiplexer&#xff09;&#xff1a;从单一通道分离出多个信号。 3、单一通道&#xff0c;可汇聚多个…

核心集:DeepCore: A Comprehensive Library for CoresetSelection in Deep Learning

目录 一、TL&#xff1b;DR 二、为什么研究核心集&#xff1f; 三、问题定义和如何做 3.1 问题定义 3.2 业界方法 3.2.1 基于几何的方法 3.2.2 基于不确定性的方法 3.2.3 基于误差/损失的方法 3.2.5 GraNd 和 EL2N 分数 3.2.6 重要性采样 3.2.7 基于决策边界的办法 …

MyBatis-Plus笔记-快速入门

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

Redis - String相关命令

目录 setgetmsetmgetsetnx、setex、psetexincr、incrby、decr、decrby、incrbyfloatappendgetrangesetrangestrlen字符串类型编码方式总结 Redis - String Redis存储的字符串&#xff0c;是直接按二进制方式存储&#xff0c;不会做任何编码转换&#xff0c;存的是什么&#xff…

优选算法合集————双指针(专题二)

好久都没给大家带来算法专题啦&#xff0c;今天给大家带来滑动窗口专题的训练 题目一&#xff1a;长度最小的子数组 题目描述&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …

本地Ollama部署DeepSeek R1模型接入Word

目录 1.本地部署DeepSeek-R1模型 2.接入Word 3.效果演示 4.问题反馈 上一篇文章办公新利器&#xff1a;DeepSeekWord&#xff0c;让你的工作更高效-CSDN博客https://blog.csdn.net/qq_63708623/article/details/145418457?spm1001.2014.3001.5501https://blog.csdn.net/qq…

2. K8S集群架构及主机准备

本次集群部署主机分布K8S集群主机配置主机静态IP设置主机名解析ipvs管理工具安装及模块加载主机系统升级主机间免密登录配置主机基础配置完后最好做个快照备份 2台负载均衡器 Haproxy高可用keepalived3台k8s master节点5台工作节点(至少2及以上)本次集群部署主机分布 K8S集群主…

文字加持:让 OpenCV 轻松在图像中插上文字

前言 在很多图像处理任务中,我们不仅需要提取图像信息,还希望在图像上加上一些文字,或是标注,或是动态展示。正如在一幅画上添加一个标语,或者在一个视频上加上动态字幕,cv2.putText 就是这个“文字魔术师”,它能让我们的图像从“沉默寡言”变得生动有趣。 今天,我们…