list的模拟实现(一)

news2024/12/23 20:45:25

在这里插入图片描述

嗨喽大家好,时隔许久阿鑫又给大家带来了新的博客,list的模拟实现(一),下面让我们开始今天的学习吧!

list的模拟实现(一)

1.list splice接口的使用

2.list尾插的实现

3.list的迭代器模拟实现

4.const迭代器

5.insert和erase的模拟实现

1.list splice接口的使用

在这里插入图片描述

int main()
{
    std::list<int> mylist1;
    mylist1.push_back(1);
    mylist1.push_back(2);
    mylist1.push_back(3);
    mylist1.push_back(4);

    auto it = find(mylist1.begin(), mylist1.end(), 3);
    mylist1.splice(++mylist1.begin(), mylist1, it);//1324
    for (auto ch: mylist1)
    {
        cout << ch << " ";

    }
    cout << endl;
	return 0;
}

在这里插入图片描述

2.list尾插的实现

在这里插入图片描述

3.list的迭代器模拟实现

原生指针的++是连续的物理空间的++。
因为类能进行运算符重载,我直接对节点进行++达不到我的要求,所以我就将节点指针封装成一个类,这个类的行为就是遍历双向循环列表
每一个类都有自己需要完成的事情,也可以是几个类互相搭配完成一件事情。

在这里插入图片描述


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

		ListNode(const T& date = T())
		:_next(nullptr)
		,_prev(nullptr)
		,_date(date)
		{}
	};

	template<class T>
	class ListIterator
	{
		typedef ListNode<T> Node;//此处传T的时候就相当于实例化
		typedef ListIterator<T> self;
	public:
		ListIterator(Node* node)//用一个节点的指针来构造
			:_node(node)
		{}
		//++it
		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;
}



T& operator*()
{
	return _node->_date;
}

T* operator->()
{
	return &_node->_date;
}


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

	private://成员是一个节点的指针,将指针封装成类来达到我们想要实现的操作
		Node* _node;
	};



	template<class T>
	class list
	{
		
	public:

		typedef ListNode<T> Node;
		typedef ListIterator<T> iterator;//若T为int相当于实例化了一个int类型的iterator

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

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

		void push_back(const T& x)
		{
			Node* newnode = new Node(x);
			Node* tail = _head->_prev;
			//head  2  3   tail  newnode
			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
		}

	private:
		Node* _head;

	};

iterator类不需要写析构函数,构造函数。节点是由链表管理的。(一般一个类不写析构函数,就不用写拷贝构造和赋值

在C、C++等语言中,指针访问结构体(struct)或联合体(union)的成员时,我们使用箭头(->)操作符。而当我们**直接访问结构体或联合体的成员(即不通过指针)时,我们使用点(.)**操作符。

注意:对于->操作符,可以得到一个指向节点有效数据的指针(下图pos坐标(中存储的是行和列)类似于节点中的_date),应该如下图注释所进行调用,但是编译器为了可读性,强行省略了一个箭头

在这里插入图片描述

struct pos
{
	int _row;
	int _col;

	pos(int row = 0,int col = 0 )
		:_row(row)
		,_col(col)
	{}

};


void list_test2()
{

	list<pos> it1;
	it1.push_back(pos(100,200));
	it1.push_back(pos(200,300));
	it1.push_back(pos(300,400));

	list<pos>::iterator it = ++it1.begin();
	while (it != it1.end())
	{
		cout << it->_col << ":" << it->_row <<endl;
		it++;
	}
	cout << endl;
}

匿名对象的临时对象可以调用非const的成员函数

4.const迭代器

const迭代器不能是普通迭代器前加const
const迭代器目标本身可以修改,指向的内容不能修改,类似const T* p

注意:不能在模板参数T前加上const

在这里插入图片描述

第一种方式:

template<class T>
class ListConstIterator
{
	typedef ListNode<T> Node;//此处传T的时候就相当于实例化
	typedef ListConstIterator<T> self;
public:
	ListConstIterator(Node* node)//用一个节点的指针来构造
		:_node(node)
	{}
	//++it
	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;
	}



	const T& operator*()
	{
		return _node->_date;
	}

	const T* operator->()
	{
		return &_node->_date;
	}


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

private://成员是一个节点的指针,将指针封装成类来达到我们想要实现的操作
	Node* _node;
};


template<class T>
class list
{
	
public:

	typedef ListNode<T> Node;
	typedef ListIterator<T> iterator;//若T为int相当于实例化了一个int类型的iterator
	typedef ListConstIterator<T> const_iterator;


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

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

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

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

在这里插入图片描述

第二种方式:不同的模板参数表达的是不同的类,正如vector< int>和vector< double>表达的是两个不同的类

template<class T,class Ref,class Ptr>
class ListIterator
{
	typedef ListNode<T> Node;//此处传T的时候就相当于实例化
	typedef ListIterator<T,Ref,Ptr> self;
public:
	ListIterator(Node* node)//用一个节点的指针来构造
		:_node(node)
	{}
	//++it
	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;
	}



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

	Ptr operator->()
	{
		return &_node->_date;
	}


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

private://成员是一个节点的指针,将指针封装成类来达到我们想要实现的操作
	Node* _node;
};

5.insert和erase的模拟实现

链表的insert没有迭代器失效,erase迭代器有失效

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

好啦,今天的内容我们就学习到这里,如果大家觉得阿鑫写的不错的话,记得留下你的一键三连哦,期待我们的下一次相遇!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

瑞昱半导体AMB82 MINI(RTL8735B)Arduino 方法介绍

介绍瑞昱半导体&#xff08;Realtek &#xff09;AMB82-Mini 物联网 AI开发板 Ameba是一个易于编程的平台&#xff0c;用于开发各种物联网应用程序。AMB82 MINI配备了各种外设接口&#xff0c;包括WiFi、BLE、GPIO INT、I2C、UART、SPI、PWM、ADC。通过这些接口&#xff0c;AM…

Reids高频面试题汇总总结

一、Redis基础 Redis是什么? Redis是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令来操作这些数据结构。Redis的主要特点是什么? 高性能:Redis将数据存储在内…

C语言代码错误(一)

今天在写选择排序代码时&#xff0c;在测试数据发现不能显示结果 1、代码如下&#xff1a; #include <stdio.h>int main(void) {int i, j; // 循环变量int MinIndex; // 保存最小的值的下标int buf; // 互换数据时的临时变量int n;printf("你想输入多少个数据n:\n…

ElasticSearch插件版本与ES版本不对应的解决方案

一、背景 最近需要给es安装ik、hanlp分词器和ingest-attachment管道&#xff0c;服务器已有的es版本为8.5.3&#xff08;似乎太新了&#xff09;&#xff0c;hanlp和ingest-attachment都没有这么高的版本&#xff0c;因此只能下载相对老的版本&#xff0c;然后自己修改配置文件…

C#同花顺下单 模拟操作版接口实现

C#同花顺下单 模拟操作版接口的实现 采用C#编程语言实现&#xff0c;对同花顺下单界面自动控制&#xff0c;将实现方法封装为DLL可以任意使用&#xff0c;支持几乎所有券商&#xff0c;不需要更换特定的券商。 比如当下最流行的QMT量化软件&#xff0c;仍然受限于特定的券商&a…

springboot小结1

什么是springboot ​ Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的&#xff0c;使用它可以做到专注于Spring应用的开发&#xff0c;而无需过多关注XML的配置。 ​ 简单来说&#xff0c;它提供了一堆依赖打包Starter&#xff0c;并已经按照使用习惯解决…

利用element实现简单右键

利用element-plus中的el-menu实现简单右键 实现如下 <template><main class"mainClass" contextmenu"showMenu($event)"> </main><el-menu:default-active"1"class"el-menu-demo"mode"vertical":col…

【Qt】Qt入门

思维导图 学习目标 这一系列是学习Qt&#xff0c;在C中&#xff0c;会发现有不少岗位的要求是熟悉Qt&#xff0c;所以Qt的学习是不能推迟的。 一、Qt的概述 1.1 Qt的特点 Qt是一个跨平台的C应用程序开发框架&#xff1a; 具有短平快的优秀特质&#xff1a;投资少&#xff0…

大模型额外篇章二:基于chalm3或Llama2-7b训练酒店助手模型

文章目录 一、代码部分讲解二、实际部署步骤(CHALM3训练步骤)1)注册AutoDL官网实名认证2)花费额度挑选GPU3)准备实验环境4)开始执行脚本5)从浏览器访问6)可以开始提问7)开始微调模型8)测试训练后的模型三、基于Llama2-7b的训练四、额外补充1)修改参数后2)如果需要访问…

windows安装SQL Server

1、下载 下载网页&#xff1a;SQL Server 下載 | Microsoft 2022版下载地址&#xff1a;https://go.microsoft.com/fwlink/p/?linkid2215158&clcid0x404&culturezh-tw&countrytw 下载结果&#xff1a;SQL2022-SSEI-Dev.exe 打开选第三个&#xff0c;下载介质&…

Cohere继Command-R+之后发布大模型Aya-23,性能超越 Gemma、Mistral 等,支持中文

前言 近年来&#xff0c;多语言大模型&#xff08;MLLM&#xff09;发展迅速&#xff0c;但大多数模型的性能依然存在显著差距&#xff0c;尤其是在非英语语言方面表现不佳。为了推动多语言自然语言处理技术的发展&#xff0c;Cohere团队发布了新的多语言指令微调模型家族——…

微信小程序文本框输入显示已经输入的字数

我们遇到这样的需求&#xff0c;就是微信小程序的输入框下面需要显示输入的字数&#xff1a; 我们通常会使用bindinput事件&#xff0c;让显示的字数等于value的长度&#xff0c;看下面的图&#xff1a; 但在实践中&#xff0c;真机测试中&#xff0c;我们会发现以下问题: 这个…

【C++】——入门基础知识超详解

目录 ​编辑 1.C关键字 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 命名空间的使用有三种方式&#xff1a; 注意事项 3. C输入&输出 示例 1&#xff1a;基本输入输出 示例 2&#xff1a;读取多个值 示例 3&#xff1a;处理字符串输入 示例 4&#xff1a;读…

2024年5月27日 十二生肖 今日运势

小运播报&#xff1a;2024年5月27日&#xff0c;星期一&#xff0c;农历四月二十 &#xff08;甲辰年己巳月辛卯日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;羊、蛇、狗 需要注意&#xff1a;鼠、鸡、龙 喜神方位&#xff1a;西南方 财神方位&#xff1a;…

vue3 vite项目配置了proxy代理情况下查看真实的接口调用地址

vite配置了proxy代理情况下如何查看真实的接口调用地址? 使用vite进行代理 在vite.config.ts配置了代理 在浏览器查看请求头和响应头发现只有代理前的url&#xff0c;没有显示代理后的路径 然后发现一个bypass函数&#xff0c;但是此函数只能修改res响应头的数据&#xff0…

指纹识别系统架构

目录 1. 系统架构 1.1 指纹采集模块 1.2 指纹处理模块 1.3 指纹登记模块 1.4 指纹识别模块 1.5 指纹识别决策模块 1.6 管理模块 1.6.1 存储管理 1.6.2 传输管理 1.6.3 安全管理 1.7 应用开放功能 1.7.1 指纹登记功能 1.7.2 指纹验证功能 1.7.3 指纹辨识功能 2. …

DM Hw6

Hw6 聚类 1ab 2abcd 3abcde 456789 1 a b 一个点不来自某个特定簇的概率是 1 − 1 K 1-\frac{1}{K} 1−K1​ 对所有 2 K 2K 2K 个点都不来自该簇的概率是 ( 1 − 1 K ) 2 K (1-\frac{1}{K})^{2K} (1−K1​)2K 则 至少一个点来自该簇的概率为 1 − ( 1 − 1 K ) 2 K 1-(1-…

vs2019 c++20 规范的 STL 库的智能指针 shared、unique 、weak 及 make_** 函数的源码注释汇总,和几个结论

智能指针的源码都在 《memory》 头文件中。因为头文件太长&#xff0c;再者本次整理是基于以前的零散的模板分析。故相当于抽取了该头文件中关于智能指针的源码进行分析&#xff0c;注释。 &#xff08;1 探讨一&#xff09;当独占指针指向数组时&#xff0c;其默认的删除器是…

二叉树——经典练习题

目录 前言&#xff1a; 一、单值二叉树 题目描述&#xff1a; 思路分析&#xff1a; 代码实现&#xff1a; 二、二叉树最大深度 题目描述&#xff1a; 思路分析&#xff1a; 代码实现&#xff1a; 三、检查两颗树是否相同 题目描述&#xff1a; 思路分析&#xff1a; 代…

EXCEL怎么计算一列数据里的最大连续重复次数?

有这样一列数据&#xff0c;怎么用EXCEL数据求出&#xff0c;重复出现的单/双的次数的最大值。 这里演示使用辅助列数据透视表。 一、单/双出现的次数的最大值 这个可不用辅助列&#xff0c;选中数据透视表将数据 单/双列放在行字段&#xff0c;和值字段&#xff0c;值字段会…