C++中链表的底层迭代器实现

大家都知道在C++的学习中迭代器是必不可少的,今天我们学习的是C++中的链表的底层迭代器的实现,首先我们应该先知道链表的底层迭代器和顺序表的底层迭代器在实现上有什么区别,为什么顺序表的底层迭代器更加容易实现,而链表的底层迭代器不容易实现,接下来小编再来告诉大家如何来实现链表的底层迭代器,学完今天这篇我相信大家对C++中的迭代器一定会有一个更加深刻的认识!大家先看今天学习的内容:

一、顺序表和链表的底层迭代器的区别

为了知道它们两个的区别,先得告诉大家顺序表的底层迭代器是如何实现的,首先大家先得明白顺序表私有成员都有什么,好方便大家来理解它们的底层迭代器是如何实现的,请看下图顺序表的私有成员变量:

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;

如图就是顺序表的私有成员变量 第一个 _start 是记录顺序表的起始位置的指针类型是 T*

_finish记录的是顺序表内末尾元素的下一个位置的指针类型是T*,_end_of_storage记录的是顺序表的目前的所有容量的下一个位置类型也是T*。

在明白了顺序表的私有成员变量的意义,并且顺序表的储存是连续的空间有点类似于数组的数据储存,所以大家也应该明白了顺序表的底层迭代器是如何实现的了吧,如果不懂请看下图操作及注释,如下图:

但是由于链表的物理结构不是连续的,所以想顺序表一样的底层迭代器实现方法是行不通的,这也是为什么在底层实现链表的迭代器中,不能通过给迭代器++来做到迭代器指向下一个元素的地址,因为链表的数据在空间中分布式随意的。那该如何去设计链表的底层迭代器呢,请大家继续往下看。

二、链表的底层迭代器该如何实现

首先先请大家看一下链表中的数据是如何分布的,如下图:

如图,可见链表中的数据是随意分布的,但是我们仍然可以用前一个节点找到下一个节点,但为什么这样子不行,不算迭代器呢,因为在C++中迭代器的定义就是通过 ++ 来找到下一个元素,接通过 * 号来拿到他这个位置的数据,这才是迭代器的规定,如下段代码的遍历效果:

如上链表的分布图,虽然我们可以拿到下一个节点的位置和这个节点的数据,但我们不是通过 ++ 和 * 来实现的,所以通过这样的方式做出的迭代器是不对的。那我们该如何实现呢,小编新学了一个方法,就是把迭代器底层封装成一个类,让它内部进项运算符重载来达到 ++ 实现像迭代器一样遍历的过程* 实现像迭代器一样拿出数据的过程,那么该如何实现呢,请大家继续往下看。

三、链表底层迭代器的实现

上面说到把迭代器封装成一个类,然后用运算符重载来达到 ++* 的过程,把它彻底改变为一个正规的迭代器,现在大家就和我一起实现这个迭代器的类:

1、首先大家要明白链表(带头双向循环链表)的结构,如下代码:

template<class T>
// 这里用结构体是因为ListNode中的每个成员都应该可以访问 没有私有成员
// 也可以使用友元来解决这个问题
struct ListNode
{
	T _data;
	ListNode* _next;
	ListNode* _prev;

	ListNode(const T& data = T())
		:_next(nullptr)
		,_prev(nullptr)
		, _data(data)
	{}
};
	template<class T>
	class list
	{
	public:
		typedef ListNode<T> Node;
	private:
		Node* _head;
	};

如上图代码,在这里我们已经知道下一步需要把链表独特的遍历方式(用前一个指针找到后一个指针)用运算符重载的改为 ++  来实现遍历和拿到数据,保证它和迭代器的实现和用法一模一样。那该如何实现这个类呢。

2、实现迭代器的类

我们需要定义一个迭代器的类,因为有普通迭代器和不可修改的迭代器,它们两个的函数大多数相同,为了减少代码量,我们加入两个模板参数来帮我们减轻代码量

	// 这里加入 Ref 和 Ptr 是为了区分普通迭代器和const迭代器的区别
	// 本来要写两份迭代器,一份可修改,一份不可修改 现在直接交给编译器去做
	template<class T , class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;

		// 链表的迭代器应该是 Node* 类型的指针
		Node* _node;

		ListIterator(Node* node)
			:_node(node)
		{}
		// 前置++
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		//前置--
		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		Self operator++(int)
		{
			Self tem(*this);
			_node = _node->_next;
			return tem;
		}
		Self operator--(int)
		{
			Self tem(*this);
			_node = _node->_prev;
			return tem;
		}
		Ptr operator->()
		{
			return &(_node->_data);
		}
		Ref operator*()
		{
			return _node->_data;
		}
		bool operator!=(const Self& it)
		{
			return _node != it._node;
		}

		bool operator==(const Self& it)
		{
			return _node == it._node;
		}
	};

以上就是今天的所有内容,希望大家会喜欢!!!

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

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

相关文章

更换Mac硬盘后如何将数据恢复到新驱动器?

在本文中&#xff0c;我们将分享几种在用新 Mac 硬盘替换旧 Mac 硬盘后从旧 Mac 硬盘恢复数据的方法。 您是否最近由于存储空间不足或损坏问题而必须更换新的Mac硬盘&#xff1f;是否要将受影响驱动器中的数据恢复到新驱动器&#xff1f;我们可以帮忙&#xff01;但是&#xf…

线性代数|机器学习-P24加速梯度下降(动量法)

文章目录 1. 概述2. 引入3. 动量法梯度下降 1. 概述 我们之前学的最速梯度下降[线搜索方法] 公式如下&#xff1a; x k 1 x k − s k ∇ f ( x k ) \begin{equation} x_{k1}x_k-s_k\nabla f(x_k) \end{equation} xk1​xk​−sk​∇f(xk​)​​ 但对于这种方法来说&#xff…

手机数据恢复篇:如何从 Android 设备内恢复数据

如何从 Android 内部存储恢复数据&#xff1f; 要从 Android 内部存储恢复已删除的文件&#xff0c;您需要一个 Android 内部存储恢复应用或程序。请继续阅读以获取可靠的 Android 数据恢复软件&#xff0c;并让它帮助您从 Android 手机的内部存储恢复数据。 是否有可能恢复 An…

【vue3-命名规范以及注意事项】

使用多字组件名 使用详细的道具定义props 在提交的代码中&#xff0c;prop定义应该总是尽可能详细&#xff0c;至少指定类型。 在声明期间&#xff0c;道具名应该始终使用camelCase。当在in-DOM模板中使用时&#xff0c;props应该是串式的。单文件组件模板和JSX可以使用keba…

sklearn之神经网络学习算法

文章目录 什么是神经网络人工神经网络的结构输入层输出层隐含层神经元的链接 近几年深度学习还是比较火的&#xff0c;尤其是在大语言模型之后&#xff0c;在本质上深度学习网络就是层数比较多的神经网络。sklearn并不支持深度学习&#xff0c;但是支持多层感知机&#xff08;浅…

AI 歌词创作:突破想象,惊艳听觉

在音乐的世界里&#xff0c;歌词是触动心灵的钥匙&#xff0c;是引发共鸣的桥梁。而如今&#xff0c;AI 歌词创作正以其惊人的力量&#xff0c;突破我们的想象&#xff0c;为我们带来前所未有的听觉盛宴。 “妙笔生词智能写歌词软件&#xff08;veve522&#xff09;”便是这场…

【机器学习-00】机器学习是什么?

在科技飞速发展的今天&#xff0c;机器学习已成为一个热门话题&#xff0c;广泛应用于各个行业和领域。那么&#xff0c;机器学习到底是什么&#xff1f;它又是如何工作的&#xff1f;本文将深入探讨机器学习的定义、原理及其在各领域的应用&#xff0c;带领读者走进这个神秘而…

QuantML-Qlib Model | ICLR 24: 基于独立Patch的时序预测模型

QuantML-Qlib Model | ICLR 24: 基于独立Patch的时序预测模型 原创 QuantML QuantML 2024年07月12日 19:23 上海 Content 论文提出了一种新的时间序列嵌入方法&#xff0c;主要观点是独立地嵌入时间序列块&#xff08;patches&#xff09;&#xff0c;而不是捕捉这些块之间的…

MySQl高级篇-主从复制

主从复制 复制的基本原理 slave会从master读取binlog来进行数据同步 MySQL复制过程分成三步&#xff1a; master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件&#xff0c;binary log events;slave将master的binary log events拷贝到它的中继日志(r…

SpringBoot+Vue实现简单的文件上传(txt篇)

SpringBootVue实现简单的文件上传 1 环境 SpringBoot 3.2.1&#xff0c;Vue 2&#xff0c;ElementUI 2 页面 3 效果&#xff1a;只能上传txt文件且大小限制为2M&#xff0c;选择文件后自动上传。 4 前端代码 <template><div class"container"><el-…

2024-07-13 Unity AI状态机2 —— 项目介绍

文章目录 1 项目介绍2 模块介绍2.1 BaseState2.2 ...State2.2.1 PatrolState2.2.2 ChaseState / AttackState / BackState 2.3 StateMachine2.4 Monster 3 其他功能4 类图 项目借鉴 B 站唐老狮 2023年直播内容。 点击前往唐老狮 B 站主页。 1 项目介绍 ​ 本项目使用 Unity 2…

SQL 字段类型-上

总 数据类型关键字描述整数迷你整型tinyint使用1个字节存储整数短整型smallint使用2个字节存储整数中整型mediumint使用3个字节存储整数标准整型int使用4个字节存储整数小数大整型bigint使用8个字节存储单进度float (.. , ..)使用4个字节 ...表示宽度 后面的... 表示小数位双精…

链接追踪系列-08.mac m1安装logstash-番外

下载地址&#xff1a;https://elasticsearch.cn/download/ 配置es相关&#xff1a; #安装plugin&#xff1a; jelexbogon bin % ./logstash-plugin install logstash-codec-json_lines启动&#xff1a;指定配置文件运行 jelexbogon bin % nohup ./logstash -f ../config…

docker安装mysql, 虚拟机连接mysql

docker已安装&#xff1a;安装教程docker和docker的安装-CSDN博客docker是容器技术&#xff08;软件&#xff09;&#xff0c;提供标准的应用镜像&#xff08;包含应用&#xff0c;和应用的依赖&#xff09;可以轻松在docker里安装应用&#xff0c;每个应用独立容器。https://b…

Linux系列--命令详解

目录 一、Linux资源管理方式 二、查询类型命令详解 三、文件管理类型命令详解 四、文件压缩与解压 五、文件编辑 六、系统命令 七、文件内容查看命令 一、Linux资源管理方式 linux操作系统采用一个文档树来组织所有的资源。这棵树的根目录的名字叫做&#xff1a;//…

Spring AOP 实现 Excel 导出统一处理

你好&#xff0c;我是柳岸花开。在实际开发中&#xff0c;经常会遇到需要导出 Excel 数据的需求。为了避免代码重复&#xff0c;我们可以使用 Spring AOP&#xff08;面向切面编程&#xff09;来实现 Excel 导出的统一处理。本文将介绍如何使用 Spring AOP 在项目中统一处理 Ex…

三参数陷波器

传统陷波器特性 传统陷波器的传递函数为&#xff1a; 传统陷波器的 Bode 图如图所示&#xff0c;根据图中曲线表明&#xff0c;当ξ 0.1、ξ 1、 ξ 10 时&#xff0c;随着ξ 值的增加&#xff0c;陷波宽度增大&#xff0c;陷波幅值也增大&#xff0c;此时&#xff0c;陷波…

线程安全(五)volatile 修饰共享变量(JIT即时编译器、指令重排序)

目录 一、volatile 简介1.1 定义1.2 volatile 的两个特性二、特性1:保证线程间的可见性示例1:普通场景1)代码示例:2)执行结果:3)总结:示例2:被 JIT 即时编译器优化1)代码示例:2)执行结果:3)原因分析:4)什么是 JIT 即时编译器?4)解决方案一:5)解决方案二:三…

三相PWM整流器PI双闭环控制Simulink

1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2017Rb&#xff09;软件。建议采用matlab2017 Rb及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff09; 2.拓扑结构&#xff1a; 3.模型算法架构&#xff1a; 4.仿真算法&#xff1a; &am…

Camunda如何通过外部任务与其他系统自动交互

文章目录 简介流程图外部系统pom.xmllogback.xml监听类 启动流程实例常见问题Public Key Retrieval is not allowed的解决方法java.lang.reflect.InaccessibleObjectException 流程图xml 简介 前面我们已经介绍了Camunda的基本操作、任务、表&#xff1a; Camunda组件与服务与…