List的模拟实现 迭代器

————————————————————
list与vector相比,插入、删除等操作实现的成本非常低,如果在C语言阶段熟悉理解过链表,那么现在实现起来list就显得比较简单,可以说操作层面上比vector更简洁,因为list没有扩容这个繁琐而耗时的操作,就不需要实现reserve函数了,

唯一的难点在于实现链表遍历,当然这里说得不是像C语言下通过原生节点跳转遍历,而是采用迭代器遍历。

STL中所有的容器都采用迭代器++ or --的方式进行访问,对于string和vector来说,迭代器是非常好理解的,得益于string和vector的物理存储空间连续,迭代器可以视作原生指针。

But,对于链表而言,每一个节点的位置都是随机存储的,如果还是使用原生节点去访问,那么势必为出现野指针导致访问权限冲突的问题。故而需要借助类和模板进行封装模拟原生指针的效果。

故而可以 得出:STL中的迭代器可以分为两类
1、原生指针
2、模拟指针效果的对象

因此文章主要谈论list迭代器的模拟实现,具体代码请参考gitee仓库👇

https://gitee.com/chxchenhaixiao/test_c/blob/master/List/List/list.h

首先需要定义节点的结构,数值+前驱指针+后继指针的结构体

template<typename T>
struct list_node{T _data;list_node<T>* _next;		//带上<T>才是一个类型噢list_node<T>* _prev;list_node(const T& val= T()):_next(nullptr),_prev(nullptr){_data=val;}
}

其次需要实现list的主题框架,我们所实现的是双向带哨兵位循环链表

template<typename T>
class list{
private:typedef list_node<T> node;	//内部typedef,方便起见node* _head;		//_head是哨兵位节点
public:list(){_head = new node;_head->_prev=_head->_next=_head;}void push_back(const T& val = x){node* new_node = new node(x);new_node->_prev = _head->_prev;_head->_prev->_next=new_node;new_node->_next = _head;_head->_prev=new_node;}//此处非最优版本,只是为了后续方便测试
}

现在我声明了一个list< int > 类型的 lst 对象,并对它进行尾插操作,使得lst存有整型数据1,2,3,4

现在需要遍历链表,就要去定义迭代器iterator

so,我们开始遍写迭代器

template<typename T>
struct _list_iterator{typedef list_node<T> node;typedef _list_iterator<T> self;node* _node;_list_iterator(node* val):_node(val){}T& operator * (){return _node->_data;}self& operator ++(){_node=_node->_next;return *this;}self& operator --(){_node=_node->_prev;return *this;}bool operator !=(const self& val)const{return _node!=val._node;}

其实这就是对原生指针的一个封装

接着,我们自然而然会想到,既然已经实现了迭代器,那么我们遍历的时候肯定要通过迭代器类型去访问,则就需要在list类中补充返回迭代器类型的成员函数begin和end

template<typename T>
class list{
private:typedef list_node<T> node;	//内部typedef,方便起见node* _head;		//_head是哨兵位节点public:typedef _list_iterator<T> iterator;	//typedef _list_iterator<T,T&> iterator;	//typedef _list_iterator<T,const T&> cosnt_iterator;list(){_head = new node;_head->_prev=_head->_next=_head;}iterator begin(){return iterator(_head->_next);}	//哨兵位下一个节点才是第一个数据iterator end(){return iterator(_head);}void push_back(const T& val = x);
}

这样就可以实现一个普通list对象的遍历了,
目前还欠缺的是const list对象的遍历实现,因此还需要补充const迭代器,const迭代器的写法可以说是照抄普通迭代器的写法了,但是为了代码变得更为简洁,可以在定义迭代器类型的时候多设置一个模板参数,变成
template<typename T,typename Ref> //Ref指引用

而list中的typedef语句可以更新为
typedef _list_iterator<T,T&> iterator;
typedef _list_iterator<T,const T&> cosnt_iterator;

list类中增设成员函数

	const_iterator begin(){return const_iterator(_head->_next);}const_iteraotr end(){return const_iterator(_head);}

到这里为止,迭代器基本上已经是大致功能健全了,list的大部分操作借助我们定义的迭代器可以说说非常容易了,这里就不做过多展开。

最后,为了方便读者更好理解,文末献上模板实例化的过程:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gRPC使用详解

起源特点主要优缺点应用场景组成部分使用方法SpringBoot集成gRPCVert.x集成gRPCNacos集成gRPC监控gRPC调用过程Java使用示例 起源 gRPC的起源可以追溯到2015年&#xff0c;当时谷歌发布了一款开源RPC框架&#xff0c;名为gRPC。gRPC的设计初衷是为了提供一种标准化、可通用和跨…

概率论中的全概率公式、贝叶斯公式解析

全概率公式 定义 全概率公式是用来计算一个事件的概率&#xff0c;这个事件可以通过几个互斥事件的并集来表示。这几个互斥事件称为“完备事件系”。实质是由原因推结果。 公式 用途 全概率公式通常用于计算一个事件的总概率&#xff0c;特别是当这个事件与几个不同的因素相关…

图书管理系统(ArrayList和LinkedList)--versions3.0

目录 一、项目要求&#xff1a; 二、项目环境 三、项目使用的知识点 四、项目代码 五、项目运行结果 六、项目难点分析 图书管理系统--versions1.0&#xff1a; 图书管理系统--versions1.0-CSDN博客文章浏览阅读981次&#xff0c;点赞29次&#xff0c;收藏17次。本文使用…

高宇辰:打造“π”型人才 | 提升之路系列(七)

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

【LeetCode: 462. 最小操作次数使数组元素相等 II + 贪心】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【傻瓜式教程】docker运行facechain

首选&#xff0c;为了防止后期docker满&#xff0c;Docker容器 - 启动报错&#xff1a;No space left on device&#xff0c;更换一下docker存储位置 1、停止Docker服务 首先停止Docker守护进程&#xff0c;可以使用以下命令&#xff1a; sudo systemctl stop docker 备份现有…

文本生成高清、连贯视频,谷歌推出时空扩散模型

谷歌研究人员推出了创新性文本生成视频模型——Lumiere。 与传统模型不同的是&#xff0c;Lumiere采用了一种时空扩散&#xff08;Space-time&#xff09;U-Net架构&#xff0c;可以在单次推理中生成整个视频的所有时间段&#xff0c;能明显增强生成视频的动作连贯性&#xff…

深度学习与神经网络pytorch版 2.3 线性代数

深度学习与神经网络pytorch版 2.3 线性代数 目录 深度学习与神经网络pytorch版 2.3 线性代数 1. 简介 2. 线性代数 2.3.1 标量 ​编辑2.3.2 向量 2.3.3 矩阵 2.3.4 张量及其性质 2.3.5 降维 2.3.6 非降维求和 2.3.7 点积 2.3.8 矩阵-向量积 2.3.9 矩阵-矩阵乘法 …

初识vue3

文章目录 1.Vue3的好处2.create-vue搭建vue3项目3.项目目录和关键文件4.组合式API - setup选项5.组合式API - reactive和ref函数①reactive②ref() 6.组合式API - computed7.组合式API - watch①基础使用 - 侦听单个数据②基础使用 - 侦听多个数据③immediate④精确侦听对象的某…

关于在Tkinter + Pillow图片叠加中出现的问题

这段时间我一直在尝试对多图层图片进行一个叠加的操作&#xff0c;想用tkinter实现出来&#xff0c;先看错误 这里我其实已经选择了图片&#xff0c;但是发现是ValueError&#xff0c;我尝试断点检测但是也无动于衷&#xff0c;因为设置变量检测的时候发现变量并没有错误&…

面试八股文(3)

文章目录 1.HashSet如何检查重复2.comparable和Comparator区别3.ConcurrentHashMap和Hashtable区别4.线程和进程5.并发与并行的区别6.为什么使用多线程7.使用多线程可能带来问题8.线程的生命周期和状态9.什么是上下文切换10.线程死锁11.产生死锁四个条件12.如何避免死锁 1.Hash…

单片机最小系统讲解

一最小系统解释&#xff1a; 面试当中常常问到的&#xff0c;一个题目什么是单片机最小系统&#xff1f; 本质上是问&#xff1f;要能够使单片机能够工作的最小组部分有哪些。 对于单片机而言&#xff0c;要想能够工作&#xff0c;就和人一样我们要有心脏推动我们身体器官的…

Docker基础(持续更新中)

# 第1步&#xff0c;去DockerHub查看nginx镜像仓库及相关信息# 第2步&#xff0c;拉取Nginx镜像 docker pull nginx# 第3步&#xff0c;查看镜像 docker images # 结果如下&#xff1a; REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 60…

【DDD】学习笔记-代码模型的架构决策

代码模型属于软件架构的一部分&#xff0c;它是设计模型的进化与实现&#xff0c;体现出了代码模块&#xff08;包&#xff09;的结构层次。在架构视图中&#xff0c;代码模型甚至会作为其中的一个视图&#xff0c;通过它来展现模块的划分&#xff0c;并定义运行时实体与执行视…

Cmake语法学习3:语法

1.双引号 1.1 命令参数 1&#xff09;介绍 命令中多个参数之间使用空格进行分隔&#xff0c;而 cmake 会将双引号引起来的内容作为一个整体&#xff0c;当它当成一个参数&#xff0c;假如你的参数中有空格&#xff08;空格是参数的一部分&#xff09;&#xff0c;那么就可以使…

Python中with管理上下文

上下文管理器 上下文管理器本质就是能够支持with操作。 任何实现了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器&#xff0c;上下文管理器对象可以使用 with 关键字。显然&#xff0c;文件&#xff08;file&#xff09;对象也实现了上下文管理器协议。 实现…

一文速学-selenium高阶操作连接已存在浏览器

前言 不得不说selenium不仅在自动化测试作为不可或缺的工具&#xff0c;在数据获取方面也是十分好用&#xff0c;能够十分快速的见到效果&#xff0c;这都取决于selenium框架的足够的灵活性&#xff0c;甚至在一些基于web端的自动化办公都十分有效。 通过selenium连接已经存在…

幻兽帕鲁能在Mac上运行吗?幻兽帕鲁Palworld新手攻略

幻兽帕鲁能在Mac上运行吗&#xff1f; 《幻兽帕鲁》目前还未正式登陆Mac平台&#xff0c;不过通过一些方法是可以让游戏在该平台运行的。 虽然游戏不能在最高配置下运行&#xff0c;但如果你安装了CrossOver这个软件&#xff0c;就可以玩了。这是为Mac、Linux和ChromeOS等设计…

oracle19C 密码包含特殊字符@ 导致ORA-12154

oracle 19C 密码包含特殊字符 出现登录失败&#xff0c;针对此问题一次说个明白 ORA-12154: TNS:could not resolve the connect identifier specified Oracle 19c之前密码是可以包含特殊字符&#xff0c;但是如果包含特殊字符需要双引号 比如oracle11g 正常 如果密码包含特殊…

MongoDB从入门到实战之MongoDB快速入门

前言 上一章节主要概述了MongoDB的优劣势、应用场景和发展史。这一章节将快速的概述一下MongoDB的基本概念&#xff0c;带领大家快速入门MongoDB这个文档型的NoSQL数据库。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战之MongoDB简介&#x1f449; MongoDB从入门到实战…