C/C++ list模拟

模拟准备

避免和库冲突,自己定义一个命名空间

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

		T _data;
	};

	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
	

	private:
		Node* _head;
	};

	
}

这里的ListNode类为什么用struct呢?

知识点:

        class:如果类里有公有,有私有,建议用

        struct:如果一个类,全部成员不做访问限定,全公有,建议用

因为下面的list类是要经常访问ListNode的,所以建议用struct

模拟实现

 模板ListNode的构造

封装节点的数据

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

	T _data;

	ListNode(const T& data)
		:_next(nullptr)
		, _prev(nullptr)
		,_data(data)
	{

	}
};

list的构造

void list()
{
	//哨兵位
	_head = new Node;
	_head->next = _head;
	_head->prev = _head;
}

定义一个哨兵位,自己指向自己。


 

push_back( )

尾插

void push_back(const T& x)
{
	Node* newnode = new Node(x);
	Node* tail == _head->prev;

	tail->_next = newnode;
	newnode->_prev - tail;
	newnode->_next = _head;
}

最后一个节点就是头节点的前一个

如果是一个空链表呢?满足条件么?

是可以的,这时候_head 和 tail都是哨兵位(head)

迭代器

说起迭代器,我们先考虑如何遍历链表吧。

我们是否可以像vector那样呢?

typedef Node* iterator;

当然是不可以的。

vector的空间是连续的,而list的空间不连续,那我们如何获取Node*呢?

定义迭代器类

我们可以定义一个类,把节点_node封装起来,来弥补空间不连续的缺陷,能像vector那样一样来进行访问。

template<class T>
class ListIterator
{
	typedef ListNode<T> Node;

	Node* _node;
};

template定义的模板参数只能供当前类或当前函数用

而且我们可以在这个类里重载想要的东西

使用时,我们就可以给每个类规范这个迭代器使用的名字,方便我们使用

typedef ListIterator<T> iterator;
template<class T>
class ListIterator
{
	typedef ListNode<T> Node;
	typedef ListIterator<T> self; // 返回自己

	Node* _node;

	self& operator++()
	{
		_node = _node->_next;
		return *this;//返回节点自己
	}

	T& operator*()
	{
		return _node->_data;//返回数据,数据类型为T
	}

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

};

iterator begin( ) 、 iterator end( )

我们实现了迭代器,我们来实现一下链表的头指针和尾指针吧

在list类里

iterator begin()
{
	//iterator it(_head->_next);
	//return it;
	
	//我们采用匿名对象
	return iterator(_head->_next);
}
iterator end()
{
	return iterator(_head;
}

测试通过

operator->( )

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

我们来测试一下下面的代码

struct pos
{
	int _row;
	int _col;

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

void test2()
{
	list<pos> lt1;
	lt1.push_back(pos(100, 100));
	lt1.push_back(pos(200, 100));
	lt1.push_back(pos(300, 100));

	list<pos>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << (*it)._row << ":" << (*it)._col << " ";
		cout << it->_row << ":" << it->_col << " ";

		++it;

	}cout << endl;

}

第一种用的是对象.成员

第二种指针->成员

第一种比较好理解,it调用operator*(),返回data数据,也就是pos,然后pos._row,pos._col来访问

第二种比较绕,这里为了可读性,省略可一个->,但如果写两个的话不符合语法,于是

cout << it.operator->()->_row << ":" << it.operator->()->_col << " ";

        第一个->是operator重载的,而第二个是原生指针的解引用

const迭代器

不能是普通迭代器前面+const修饰。

如:const iterator const 

const迭代器目标本身可以修改,指向的内容不能修改 , 

类似:const T* p

p可以修改,*p不能修改

因为T* 和 T&,这里我们可以写一个和迭代器一样的const迭代器类,但我们也可以类模板,传不同的参数,形成不同的类,让编译器帮我们实现。避免了写连个差不多重复的类,减少代码量

insert( )

//在pos前插入val
iterator insert(iterator pos, const T& val)
{
	Node* pNewNode = new Node(val);
	Node* pCur = pos._node;

	pNewNode->_prev = pCur->_prev;
	pNewNode->_next = pCur;
	pNewNode->_prev->_next = pNewNode;
	pCur->_prev = pNewNode;

	return iterator(pNewNode);
}

erase( )

//删除pos节点
iterator erase(iterator pos)
{
	Node* pDel = pos._node;
	Node* pRet = pDel->_next;

	pDel->_prev->_next = pDel->_next;
	pDel->_next->_prev = pDel->_prev;
	delete pDel;

	return iterator(pRet);
}

clear()

void clear()
{
	Node* cur = _head->_next;

	while (cur != _head)
	{
		//从头开始删(从左向右)
		_head->_next = cur->_next;
		delete cur;
		cur = _head->_next;
	}

	_head->_next = _head->_prev = _head;
}

~list()

~list()
{
	clear();
	delete _head;
	_head = nullptr;
}

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

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

相关文章

低代码平台赋能企业全面数字化转型

引言&#xff1a;在当今这个日新月异的数字化时代&#xff0c;企业正面临着前所未有的机遇与挑战。为了保持竞争力并实现可持续发展&#xff0c;企业亟需进行全面的数字化转型。而低代码平台作为数字化转型的重要工具&#xff0c;正以其独特的优势赋能企业&#xff0c;推动其向…

Ollama完整教程:本地LLM管理、WebUI对话、Python/Java客户端API应用

老牛同学在前面有关大模型应用的文章中&#xff0c;多次使用了Ollama来管理和部署本地大模型&#xff08;包括&#xff1a;Qwen2、Llama3、Phi3、Gemma2等&#xff09;&#xff0c;但对Ollama这个非常方便管理本地大模型的软件的介绍却很少。 目前&#xff0c;清华和智谱 AI 联…

[计网初识1] TCP/UDP

学习内容 1.TCP建立链接的3次握手&#xff0c;断开连接的4次挥手 2.TCP报文段组成 内容 1.TCP 建立连接的3次握手? 假设主动方是客户端&#xff0c;被动方是服务端。 第一次 客户端给服务端发送 “hello,我是客户端” (TCP段中 SYN1) 第二次 服务端给客户端发送"我接…

汽车免拆诊断案例 | 2016款保时捷Macan车发动机故障灯异常点亮

故障现象  一辆2016款保时捷Macan车&#xff0c;搭载CYP发动机&#xff0c;累计行驶里程约为11.2万km。车主进厂反映&#xff0c;发动机故障灯异常点亮。 故障诊断  接车后试车&#xff0c;发动机怠速无明显异常&#xff0c;组合仪表上的发动机故障灯异常点亮。用故障检测仪…

AI in Finance 金融领域AI应用-基于DeepNLP AI App Store 真实用户评论打分和排名

AI在金融领域应用 AI in Finance 金融服务领域的AI应用和传统的金融智能应用不同。传统金融智能应用包括如风险评估 (Risk assessment), 风险管理&#xff08;Risk management), 欺诈检测 (Fraud Detection&#xff09;等等。 通用AI大模型和人工智能应用如ChatGPT&#xff0c…

echart5.5.1版本,倒三角柱状图

加载方法 initChart1(title, id, tag) {var myChart echarts5.init(this.$refs[id]);const _this this;var option {title:{text: title||"",show: title?true:false,top: 24,left: 24},grid:{left: 54,top: 74,bottom: 44,right: 30,},xAxis: {type: category,d…

1996-2023年各省农业总产值数据(无缺失)

1996-2023年各省农业总产值数据&#xff08;无缺失&#xff09; 1、时间&#xff1a;1996-2023年 2、来源&#xff1a;国家统计局、各省年鉴 3、指标&#xff1a;农业总产值 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农业总产值是…

CSS关于居中的问题

文章目录 1. 行内和块级元素自身相对父控件居中1.1. 块级元素相对父控件居中1.2. 行内元素相对于父控件居中 2. 实现单行文字垂直居中3. 子绝父相实现子元素的水平垂直居中3.1. 方案一3.1.1. 示例 3.2. 方案二3.2.1. 示例 3.3. 方案三(推荐)3.3.1. 示例 3.4. 方案四(了解一下) …

高盛开源的量化金融 Python 库

GS Quant GS Quant是用于量化金融的Python工具包&#xff0c;建立在世界上最强大的风险转移平台之一之上。旨在加速量化交易策略和风险管理解决方案的开发&#xff0c;凭借25年的全球市场经验精心打造。 它由高盛的定量开发人员&#xff08;定量&#xff09;创建和维护&#…

2970.力扣每日一题7/10 Java(暴力枚举)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 解题思路 解题方法 时间复杂度 空间复杂度 Code 解题思路 incre…

对智能的研究正在悄悄地诱发复杂取代科学

随着智能人工智能的发展&#xff0c;传统科学研究方法可能面临新的挑战或者被扩展。人工智能的发展带来了大数据分析、机器学习、深度学习等新的工具和方法&#xff0c;这些方法在处理复杂系统和大规模数据方面表现出色&#xff0c;使得科学研究变得更加多样化和复杂化。对智能…

stm32 开发板可以拿来做什么?

STM32开发板可以用来做许多不同的事情&#xff0c;具体取决于您的应用需求和编程能力。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&#xff0c;敲个22就可…

iMazing 3.0.3.1Mac中文破解版下载安装激活

今天&#xff0c;小编要分享的是Mac下一款可以帮助用户管理IOS设备的软件——iMazing&#xff0c;之前&#xff0c;小编也分享的过类似的软件&#xff0c;iMazing却有独特之处。小子这次带来的是3.0.3.1版本。 iMazing 3是一款iOS设备管理软件&#xff0c;该软件支持对基于iOS…

记录一次微信小程序申诉定位权限过程

1 小程序接到通知&#xff0c;检测到违规&#xff0c;需要及时处理&#xff0c;给一周的缓冲时间&#xff0c;如果到期未处理&#xff0c;会封禁能力&#xff08;2023-11-17&#xff09; 2 到期后&#xff0c;仍未处理&#xff0c;封禁能力&#xff08;2023-11-24&#xff09; …

云视频监控中的高效视频转码策略:视频汇聚EasyCVR平台H.265自动转码H.264能力解析

随着科技的快速发展&#xff0c;视频监控技术已经广泛应用于各个领域&#xff0c;如公共安全、商业管理、教育医疗等。与此同时&#xff0c;视频转码技术作为视频处理的关键环节&#xff0c;也在不断提高视频的质量和传输效率。 一、视频监控技术的演进 视频监控技术的发展历…

传言称 iPhone 16 Pro 将支持 40W 快速充电和 20W MagSafe

目前&#xff0c;iPhone 15 和 iPhone 15 Pro 机型使用合适的 USB-C 电源适配器可实现高达 27W 的峰值充电速度&#xff0c;而 Apple 和授权第三方的官方 MagSafe 充电器可以高达 15W 的功率为 iPhone 15 机型进行无线充电。所有四款 iPhone 15 机型均可使用 20W 或更高功率的电…

zabbix服务器运维命令

查看磁盘大小 df -h 看挂载点是/的项目看内存使用大小 free -h查看cpu的大小和负载 top -c查看库大小 mysql -u root -p select table_schema as 数据库, sum(table_rows) as 记录数,sum(truncate(data_length/1024/1024, 2)) as 数据容量(MB), sum(truncate(index_length/…

“论基于构件的软件开发方法及其应用”写作框架,软考高级论文,系统架构设计师论文

论文真题 基于构作的软件开发 (Component-Based Software Development&#xff0c;CBSD) 是一种基于分布对象技术、强调通过可复用构件设计与构造软件系统的软件复用途径。基于构件的软件系统中的构件可以是COTS &#xff08;Commercial-Off-the-Shelf&#xff09;构件&#x…

Linux配置仓库,安装软件

在Linux中安装软件&#xff0c;必须得配置仓库&#xff0c;挂载&#xff0c;才能安装成功 1.选择使用的虚拟机&#xff0c;右键点击“设置” 2.点击“CD/DVD”&#xff0c;勾选“设备状态”中的“已连接”和启动时链接&#xff0c;选择ISO映像文件 3..开启虚拟机 4.配置仓库…

利用 Selenium 自动化抓取 Web of Science 论文数据:以 IEEE SENSORS JOURNAL 为例

在当今数字化时代&#xff0c;科研工作者面临着海量学术信息的挑战。有效地收集、筛选和分析相关领域的最新研究成果&#xff0c;对于保持科研竞争力至关重要。然而&#xff0c;手动检索和整理学术文献不仅耗时耗力&#xff0c;还容易出现疏漏。为了解决这一问题&#xff0c;我…