C++入门 list的模拟实现

目录

list的节点类

 list的迭代器类

list的模拟实现


要模拟实现list,必须要熟悉list的底层结构以及其接口的含义,通过之前学习,这些内容已基本掌握,现在我们来模拟实现list。

参照带头双向循环链表的结构,我们可以建立以下三个类来模拟实现list 


list的节点类

	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;

		// 构造函数 
		ListNode(const T& data = T())
			:_next(nullptr),
			_prev(nullptr),
			_data(data)
		{}
	};


 list的迭代器类

将原生态指针进行封装,因迭代器使用形式与指针完全相同,因此在自定义的类中必须实现以下方法:

  1. 指针可以解引用,迭代器的类中必须重载operator*()
  2. 指针可以通过->访问其所指空间成员,迭代器类中必须重载oprator->()
  3. 指针可以++向后移动,迭代器类中必须重载operator++()与operator++(int),至于operator--()/operator--(int)释放需要重载,根据具体的结构来抉择,双向链表可以向前移动,所以需要重载,如果是forward_list就不需要重载--
  4. 迭代器需要进行是否相等的比较,因此还需要重载operator==()与operator!=()
	template<class T, class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;
		Node* _node;
		//
		// 构造
		ListIterator(Node* node)
			:_node(node)
		{}        
        //
		// 迭代器支持移动
		// ++it;
		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;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}
		//
		// 迭代器支持比较
		bool operator!=(const Self& it)
		{
			return _node != it._node;
		}

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

迭代器类不需要析构函数,我们只要能够访问list中的元素即可,访问完不需要析构节点。

可以这样理解:这里的Self是当前这个节点,通过类模板又被细化为普通类型,引用类型,指针类型,以int代替T来实例化,这时候ListIterator中的T告诉迭代器是什么类型(int),Ref代替引用(int&),Ptr代替指针(int*)。而这里的Self可以当作节点本身。


list的模拟实现

namespace bite
{
	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;

		// 构造函数 
		ListNode(const T& data = T())
			:_next(nullptr),
			_prev(nullptr),
			_data(data)
		{}
	};

	template<class T, class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;
		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 tmp(*this);
			_node = _node->_next;

			return tmp;
		}

		Self& operator--(int)
		{
			Self tmp(*this);
			_node = _node->_prev;

			return tmp;
		}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr 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
	{
		typedef ListNode<T> Node;
	public:
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const T*> const_iterator;

		iterator begin()
		{
			//iterator it(_head->_next);
			//return it;
			return iterator(_head->_next);
		}

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

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator end() const
		{
			return const_iterator(_head);
		}

		list()
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
		}

		void push_back(const T& x)
		{
			insert(end(), x);
		}

		void pop_back()
		{
			erase(--end());
		}

		void push_front(const T& x)
		{
			insert(begin(), x);
		}

		void pop_front()
		{
			erase(begin());
		}

		// 不会发生迭代器失效
		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(x);
			Node* prev = cur->_prev;

			// prev  newnode  cur
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);
		}

		// erase 后 pos失效了,pos指向节点被释放了
		iterator erase(iterator pos)
		{
			assert(pos != end());

			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			prev->_next = next;
			next->_prev = prev;

			delete cur;

			return iterator(next);
		}

	private:
		Node* _head;
	};
}

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。因此使用erase之后需要对迭代器进行赋值刷新

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

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

相关文章

ConvMixer 论文与代码解析

paper&#xff1a;Patches Are All You Need? official implementation&#xff1a;https://github.com/locuslab/convmixer 精度上去了&#xff0c;推理速度只有卷积和ViTs的四分之一&#xff01; 出发点 文章讨论了卷积神经网络&#xff08;CNN&#xff09;在视觉任务中…

#### 广告投放 ####

以巨量引擎为例&#xff1a; 计费模式 eCPM&#xff08;expected Cost Per Mile&#xff0c;估计千次展示收入&#xff09; 概括&#xff1a; ecpm为千次展示的预估收益&#xff0c;是广告平台用来给广告排序的指标。 注意是展示而不是千次点击收益&#xff0c;展示了可能不…

从0到1:亮数据浏览器,为数据采集工作注入全新动力

亮数据浏览器提升数据采集效率 一、 导言1.1 引入亮数据浏览器的重要性1.2 简要介绍本文将涉及的主题和内容 二、 亮数据浏览器简介2.1. 什么是亮数据浏览器2.2. 亮数据浏览器的特点和优势 三、优化数据采集的核心功能3.1 自动化数据采集3.1.1 通过亮数据浏览器实现自动化数据采…

LangChain入门之 GPT 和小范大人不太熟?

前言 嗨&#xff0c;大家好&#xff01;我是海鸽。 《庆余年2》刚刚完结&#xff0c;热度不减&#xff0c;我忍不住好奇&#xff1a;我们的AI伙伴GPT&#xff0c;是否也对剧中那位机智过人的小范大人有所耳闻&#xff1f; 不仅如此&#xff0c;最近我们还尝试了LangChain的调…

Xcode安装Simulator失败问题解决方法

Xcode安装Simulator_Runtime失败&#xff0c;安装包离线安装保姆级教程 Xcode更新之后有时候会提示要安装模拟器运行时环境&#xff0c;但是用Xcode更新会因为网络原因&#xff0c;我觉得基本上就是因为苹果服务器的连接不稳定导致的&#xff0c;更可气的是不支持断点续…

介绍几种 MySQL 官方高可用方案

前言&#xff1a; MySQL 官方提供了多种高可用部署方案&#xff0c;从最基础的主从复制到组复制再到 InnoDB Cluster 等等。本篇文章以 MySQL 8.0 版本为准&#xff0c;介绍下不同高可用方案架构原理及使用场景。 1.MySQL Replication MySQL Replication 是官方提供的主从同…

记录dinky0.6.7+flink1.14.5集成问题

先说一句mmp&#xff0c;这个jar包冲突搞吐我。如果有遇到math3问题需要注意少个包 看相关issue 以下为flink的lib目录 一、yarn-application和perjob模式 yarn session模式不依赖dlink-app-1.14-0.6.7-jar-with-dependencies.jar这个包&#xff0c;。但是yarn-application…

新能源行业知识体系-------蒙西电网需求侧响应

新能源行业知识体系-------主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/139946830 目录 一、背景介绍二、需求响应电能量收益介绍三、超额回收需求响应减免收益介绍四、参与需求侧响应五、蒙西电力现货特点六、交易中…

1012:Joseph

网址如下&#xff1a; OpenJudge - 1012:Joseph 其中一个解法 只想到了一个快速找到下一位处决的人的方法&#xff0c;本质上还是遍历&#xff0c;暂时没想到更优的方法了 代码如下&#xff1a; #include<cstdio> int k;bool judge(int tt, int m, int r){if(tt k) …

GPU技术全景:推动未来计算的新动力-4

7.中国厂家 在中国市场&#xff0c;也有几家本土企业在GPU领域崭露头角&#xff0c;虽然市场份额相对较小&#xff0c;但在国产替代和自主可控的浪潮下发展迅速&#xff0c;包括但不限于&#xff1a; •沐曦集成电路、壁仞科技、燧原科技、登临科技、摩尔线程等&#xff0c…

信号处理——时频分析

经典傅里叶变换的限制&#xff1a; 1、只能反映信号的整体特性&#xff1b;&#xff08;完全是时域或频域&#xff09; 2、要求信号满足平稳条件&#xff1b; 3、必须获得时域中的全部信息。 所以引入时频分析&#xff0c;同时使用时间和频率的联合函数来表示信号。 1 时频…

单段时间最优S型速度规划算法

一&#xff0c;背景 在做机械臂轨迹规划的单段路径的速度规划时&#xff0c;除了参考《Trajectory Planning for Automatic Machines and Robots》等文献之外&#xff0c;还在知乎找到了这位大佬 韩冰 写的在线规划方法&#xff1a; https://zhuanlan.zhihu.com/p/585253101/e…

Java基础知识-线程

Java基础知识-线程 1、在 Java 中要想实现多线程代码有几种手段&#xff1f; 1. 一种是继承 Thread 类 2. 另一种就是实现 Runnable 接口 3. 最后一种就是实现 Callable 接口 4. 第四种也是实现 callable 接口&#xff0c;只不过有返回值而已 2、Thread 类中的 start() 和 …

AI大模型会有意识的出千吗?

1. 引言 1.1 研究背景&#xff0c;AI系统中的规范游戏问题 在人工智能(AI)系统的发展过程中&#xff0c;规范游戏(specification gaming)一直是一个令研究者们头疼的问题。规范游戏指的是AI系统学习到一些意想不到的行为&#xff0c;这些行为虽然能够获得高奖励&#xff0c;但…

万字长文,解读大模型技术原理(非常详细)零基础入门到精通,收藏这一篇就够了

大模型是指具有大规模参数和复杂计算结构的机器学习模型。 本文从大模型的发展历程出发&#xff0c;对大模型领域的各个技术细节进行详细解读&#xff0c;供大家在了解大模型基本知识的过程中起到一定参考作用。 一、大模型的定义 大语言模型作为一个被验证可行的方向&#x…

客户案例|某 SaaS 企业租户敏感数据保护实践

近年来&#xff0c;随着云计算技术的快速发展&#xff0c;软件即服务&#xff08;SaaS&#xff09;在各行业的应用逐渐增多&#xff0c;SaaS 应用给企业数字化发展带来了便捷性、成本效益与可访问性&#xff0c;同时也带来了一系列数据安全风险。作为 SaaS 产品运营服务商&…

注意!!2024下《系统架构设计师》易混淆知识点来了,赶紧收藏

宝子们&#xff0c;在复习软考系统架构设计师中&#xff0c;是不是觉得有很多知识点含义比较相近&#xff0c;很多友友刚看的时候&#xff0c;估计会像我一样把它们弄混&#xff0c;作为一个软考老鸟&#xff0c;在这里给大家整理了系构学习过程中易混淆的知识点&#xff0c;大…

Part 8.3.2 树的直径

树的直径被定义为树上最远的两点间的距离。 关于求树的直径的两种方式 HXY造公园 题目描述 现在有一个现成的公园&#xff0c;有 n n n 个休息点和 m m m 条双向边连接两个休息点。众所周知&#xff0c;HXY 是一个 SXBK 的强迫症患者&#xff0c;所以她打算施展魔法来改造…

彩虹PLM系统:引领汽车行业的数字化转型

彩虹PLM系统&#xff1a;引领汽车行业的数字化转型 彩虹PLM系统作为汽车行业数字化转型的引领者&#xff0c;凭借其卓越的技术实力和丰富的行业经验&#xff0c;为汽车行业带来了全面的解决方案。以下是彩虹PLM系统如何引领汽车行业数字化转型的详细分析&#xff1a; 一、整合全…

虚拟机使用的是此版本 VMware Workstation 不支持的硬件版本

复制了同事的VMware镜像&#xff0c;但是他的软件版本和我的不同&#xff0c;于是乎出现了这个报错&#xff1a;虚拟机使用的是此版本 VMwareWorkstation 不支持的硬件版本。 模块“Upgrade”启动失败。 解决办法&#xff0c;直接改.vmx文件的版本信息&#xff1a; 以文本格式打…