C++系列之list的模拟实现

news2024/11/18 11:32:46

在这里插入图片描述

💗 💗 博客:小怡同学
💗 💗 个人简介:编程小萌新
💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞

list的节点类

template
struct list_Node
{
public:
list_Node* _prev;
list_Node* _next;
T _val;
list_Node(const T& val = T())
{
_prev = _next = nullptr;
_val = val;
}
};`

list的迭代器类

//这里写入多个参数的目的是区分const迭代器
//传入不同的模板就会有不同的类
template<class T,class Ref ,class Ptr>
struct list_iterator
{
	public:
		typedef list_Node<T> Node;
		typedef list_iterator<T,Ref,Ptr> self;
		list_iterator(Node* node = nullptr)
		{
			_node = node;
		}
		list_iterator(const self& i)
		{
			_node(i._node);
		}
		//const对象不改变原数据
		T& operator*()
		{
			return _node->_val;
		}
		T* operator->()
		{
			return &_node->val;
		}
		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			self tmp(_node);
			_node = _node->_next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self& operator--(int)
		{
			self tmp(_node);
			_node = _node->_prev;
			return tmp;
		}
		bool operator!=(const self& l)
		{
			return _node != l._node;
		}
		bool operator==(const self& l)
		{
			return _node == l._node;
		}

		Node* _node;
	};

构造函数

list(int n, const T& value = T())
{
	_head = new Node();
	_head->_prev = _head;
	_head->_next = _head;
	while (n--)
	{
		push_back(value);
	}
}
template <class Intiterator>
list(Intiterator first, Intiterator last)
{
	//这三行代码的作用是制造一个头结点
	_head = new Node();
	_head->_prev = _head;
	_head->_next = _head;
	
	while (first != last)
	{
		push_back(*first);
		first++;
	}
}
list(const list<T>& l)
{
	_head = new Node();
	_head->_prev = _head;
	_head->_next = _head;
	//这里制造一个list对象,构建与l对象一样的元素,在与*this进行调换。
	list<T> tmp (l.begin(),l.end());
	swap(tmp);
}	

析构函数

~list()
{
	clear();//复用clear()函数,如果元素是自定义类型,则一一析构,
	delete _head;
	_head = nullptr;
}

赋值运算符=

list<T>& operator=(const list<T> l)
{
	swap(l);
	return *this;
}

迭代器的使用


iterator begin()
{
	return iterator(_head->_next);
}
iterator end()
{
	return itertor(_head);
}
//const对象迭代器的使用返回的是const指针(实际上迭代器是一个模板,只是类型不同)
const_iterator begin()const
{
	return const_iterator(_head->_next);
}
const_iterator end()const
{
	return itertor(_head);
}		

list的元素大小和判空

size_t size()const//const与非const对象都可调用
{
	return _size;
}
bool empty()const
{
	return _size == 0;
}

访问list的头节点与尾节点

T& front()
{
	return _head->_next->_val;
}
const T& front()const
{
	return _head->_next->_val;
}
T& back()
{
	return _head->_prev->_val;
}
const T& back()const
{
	return _head->_prev->_val;
}

尾插,尾删,头插,尾删,插入,删除,交换,清空

//这里使用了函数的调用
void push_back(const T& val)
{
	insert(end(), val); 
}
void pop_back() 
{ 
	erase(--end()); 
}
void push_front(const T& val) 
{ 
	insert(begin(), val); 
}
void pop_front() 
{ 
	erase(begin());
}
// 在pos位置前插入值为val的节点
//这里不会发生迭代器的失效,迭代器没有被改变,返回时返回pos之前的迭代器
iterator insert(iterator pos, const T& val)
{
	Node* newnode = new Node(val);
	Node* node_pos = pos.Node;
	Node* prev = node_pos->_prev;
	Node* next = node_pos->_next;
	prev->_next = next;
	next->_prev = prev;
	return newnode;
}
// 删除pos位置的节点,返回该节点的下一个位置
//这里发生迭代器的失效。指向pos指针变成野指针,返回时需要更新到该节点的下一个位置
iterator erase(iterator pos)
{
	Node* node_pos = pos.Node;
	Node* node_next = pos.Node->_next;
	node_pos->_prev->_next = node_pos->_next;
	node_next->_prev = node_pos->_prev;
	delete node_pos;
	return iterator(node_next);
}
//清除链表,只保留头节点
void clear()
{
	iterator it = begin();
	while (it != end())
	{
		erase(it);
	}
		_head->_prev = _head;
		_head->_next = _head;
}
//交换链表
void swap(const list<T>& L)
{
	Node* tmp = L._head;
	L._head = tmp;
	tmp = _head;
}
#include  <assert.h>
#include <iostream>
using namespace std;
namespace zjy
{
	template<class T>
	struct list_Node
	{
	public:
		list_Node* _prev;
		list_Node* _next;
		T _val;
		list_Node(const T& val = T())
		{
			_prev = _next = nullptr;
			_val = val;
		}
	};
	template<class T,class Ref ,class Ptr>
	struct list_iterator
	{
	public:
		typedef list_Node<T> Node;
		typedef list_iterator<T,Ref,Ptr> self;
		list_iterator(Node* node = nullptr)
		{
			_node = node;
		}
		list_iterator(const self& i)
		{
			_node(i._node);
		}
		T& operator*()
		{
			return _node->_val;
		}
		T* operator->()
		{
			return &_node->val;
		}
		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			self tmp(_node);
			_node = _node->_next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self& operator--(int)
		{
			self tmp(_node);
			_node = _node->_prev;
			return tmp;
		}
		bool operator!=(const self& l)
		{
			return _node != l._node;
		}
		bool operator==(const self& l)
		{
			return _node == l._node;
		}

		Node* _node;
	};

	template<class T>
	class list
	{
	public:
		typedef list_Node<T> Node;
		typedef list_iterator<T,T&,T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;
		list()
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;
		}
		
		/*list(int n, const T& value = T())
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;
			while (n--)
			{
				Node* newnode = new Node(value);
				Node* tail = _head->_prev;
				tail -> _next = newnode;
				newnode->_prev = _head;

				newnode->_next = _head;
				_head->_prev = newnode;
				tail = newnode;
			}
		}*/
		list(int n, const T& value = T())
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;
			while (n--)
			{
				push_back(value);
			}
		}

		/*template <class Intiterator>
		list(Intiterator first, Intiterator last)
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;

			Node* begin= first._node;
			Node* end = last._node;
			Node* tail = _head->_prev;
			while (begin != last)
			{
				tail->_next = begin;
				begin->_prev = tail;

				begin->_next = _head;
				_head->_prev = begin;
				
				tail = begin;
				begin++;
			}
		}*/
		template <class Intiterator>
		list(Intiterator first, Intiterator last)
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;

		
			while (first != last)
			{
				push_back(*first);
				first++;
			}

		}
		void  swap(const list<T>& L)
		{
			Node* tmp = L._head;
			L._head = tmp;
			tmp = _head;

		}

		list(const list<T>& l)
		{
			_head = new Node();
			_head->_prev = _head;
			_head->_next = _head;

			list<T> tmp (l.begin(),l.end());
			swap(tmp);
		}


		list<T>& operator=(const list<T> l)
		{
			swap(l);
			return *this;
		}

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


		iterator begin()
		{
			return iterator(_head->_next);
		}
		iterator end()
		{
			return itertor(_head);
		}
		const_iterator begin()const
		{
			return const_iterator(_head->_next);
		}
		const_iterator end()const
		{
			return const_itertor(_head);
		}
		size_t size()const
		{
			return _size;
		}

		bool empty()const
		{
			return _size == 0;
		}
		T& front()
		{
			return _head->_next->_val;
		}
		const T& front()const
		{
			return _head->_next->_val;
		}
		T& back()
		{
			return _head->_prev->_val;
		}

		const T& back()const
		{
			return _head->_prev->_val;
		}
		void push_back(const T& val) {
			insert(end(), val); 
		}
		void pop_back() { erase(--end()); }
		void push_front(const T& val) { insert(begin(), val); }
		void pop_front() { erase(begin()); }
		// 在pos位置前插入值为val的节点
		iterator insert(iterator pos, const T& val)
		{
			Node* newnode = new Node(val);
			Node* node_pos = pos.Node;

			Node* prev = node_pos->_prev;
			Node* next = node_pos->_next;
			
			prev->_next = next;
			next->_prev = prev;


			return newnode;
		}
		// 删除pos位置的节点,返回该节点的下一个位置
		iterator erase(iterator pos)
		{
			Node* node_pos = pos.Node;
			Node* node_next = pos.Node->_next;

			node_pos->_prev->_next = node_pos->_next;
			node_next->_prev = node_pos->_prev;

			delete node_pos;

			return iterator(node_next);
		}

		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				erase(it);
				
			}
			_head->_prev = _head;
			_head->_next = _head;
		}

		void test()
		{
			Node* tmp = _head->_next;
			while (tmp != _head)
			{
				cout << tmp->_val << endl;
				tmp = tmp->_next;
			}
		}
	private:
		Node* _head;
		size_t _size;
	};
}

在这里插入图片描述

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

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

相关文章

Tomcat服务部署和优化

目录 一、Tomcat&#xff1a; 1、Tomcat作用&#xff1a; 2、Tomcat的核心组件&#xff1a; 3、servlet作用&#xff1a; 4、Tomcat的核心功能&#xff1a; 二、tomcat配置 一、Tomcat&#xff1a; 是一个开源的web应用服务器&#xff0c;nginx主要处理静态页面&#xff…

不再受害:如何预防和应对.mallab勒索病毒攻击

导言&#xff1a; 我们的数据成了我们的珍宝&#xff0c;但也成了黑客们追逐的目标。其中&#xff0c;.mallab勒索病毒就是一个充满阴谋和神秘的数字威胁&#xff0c;它采用高度复杂的方法将您的数据锁在数字牢笼中。本文91数据恢复将深入探讨.mallab勒索病毒的起源、工作方式…

【RabbitMQ 实战】12 镜像队列

一、镜像队列的概念 RabbitMQ的镜像队列是将消息副本存储在一组节点上&#xff0c;以提高可用性和可靠性。镜像队列将队列中的消息复制到一个或多个其他节点上&#xff0c;并使这些节点上的队列保持同步。当一个节点失败时&#xff0c;其他节点上的队列不受影响&#xff0c;因…

视频转换器WinX HD Video Converter mac中文特点介绍

WinX HD Video Converter mac是一款功能强大的视频转换器&#xff0c;它可以将各种不同格式的视频文件转换为其他视频格式&#xff0c;以便用户在各种设备上进行播放。WinX HD Video Converter是一个功能强大、易于使用的视频转换器&#xff0c;适用于各种类型的用户&#xff0…

可图性判断(图论)

如图所示&#xff1a; 1.去arr[i]首元素&#xff0c; 后面arr[i]个元素减一 2.排序&#xff0c;以此类推 3.最后如果出现负数则不可图 4.最后元素为0&#xff0c;则可图 问题 L: Degree Sequence of Graph G代码如下&#xff1a;

C#版字节跳动SDK - SKIT.FlurlHttpClient.ByteDance

前言 在我们日常开发工作中对接第三方开放平台&#xff0c;找一款封装完善且全面的SDK能够大大的简化我们的开发难度和提高工作效率。今天给大家推荐一款C#开源、功能完善的字节跳动SDK&#xff1a;SKIT.FlurlHttpClient.ByteDance。 项目官方介绍 可能是全网唯一的 C# 版字节…

基于nodejs+vue全国公考岗位及报考人数分析

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

iOS的应用生命周期

在iOS的原生开发中&#xff0c;我们需要特别关注两个东西&#xff1a;AppDelegate和ViewController。我们主要的编码工作就是在AppDelegate和ViewControlle这两个类中进行的。它们的类图如下图所示&#xff1a; AppDelegate是应用程序委托对象&#xff0c;它继承了UIResponder类…

抖音上怎么挂小程序?制作小程序挂载抖音视频

公司企业商家现在已经把抖音作为营销的渠道之一&#xff0c;目前抖音支持短视频挂载小程序&#xff0c;可方便做营销。以下给大家分享这一操作流程。 一、申请自主挂载能力 首先需要在抖音开放平台官网注册一个抖音小程序账号&#xff0c;然后申请短视频自主挂载能力。 二、搭…

Kubernetes技术与架构-存储 2

在Kubernetes集群中&#xff0c;一块持久化存储空间是可以被回收再利用&#xff0c;简称PV&#xff0c;即PersistentVolume&#xff0c;Pod实例需要使用PV的时候&#xff0c;可以使用PVC定义申请PV存储资源&#xff0c;PVC是PersistentVolumeClaim的简称&#xff0c;PV的申请分…

Git(SourceTree)变基操作使用

文章目录 一、变基的使用场景二、Source Tree上的变基操作1. 准备两个分支dev1和master2. 切换到dev1中&#xff0c;并选中master中提交的代码3. 鼠标右键&#xff0c;选择变基&#xff0c;弹出对话框选择确定。 变基就是rebase操作 一、变基的使用场景 假设分支a和分支b 在分…

Day12力扣打卡

打卡记录 找出满足差值条件的下标 II&#xff08;双指针维护最大最小&#xff09; 链接 采用双指针保留间隔 indexDifference 进行遍历&#xff0c;求出慢指针对应一路遍历过来的最大值和最小值。 class Solution { public:vector<int> findIndices(vector<int>…

【排序】js简单实现前端数组排序,多字段数组对象排序,字符串排序,数字排序等

数组对象排序&#xff08;多字段排序&#xff09; 排序前&#xff1a; 排序后&#xff1a; data() {return {list: [{ks: 外科,child_ks: 泌尿外科,xz: 外科一组,doctor: 小明,num: 18,num2: 19,num3: 20},{ks: 中医科,child_ks: 中医男科,xz: 外科一组,doctor: 小红,num: …

当生成式AI遇到业务流程管理,大语言模型正在变革BPM

生成式AI对各领域有很大影响&#xff0c;一个方面在于它改变了很多固有业务的工作流。 工作流&#xff08;Workflow&#xff09;是业务流程的一种实现方式&#xff0c;一个业务流程往往包含多个工作流范式以及相关的数据、组织和系统。 因此&#xff0c;提及工作流必然离不开业…

(el-Table)操作(不使用 ts):Element-plus 中 Table 多选框的样式等的调整

Ⅰ、Element-plus 提供的 Table 表格组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Table 组件情况&#xff1a; 其一、Element-ui 自提供的 Table 代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环境…

Java练习题2020-2

"统计1到N的整数中,除了1和自身之外&#xff0c;至少还能被两个数整除的数的个数 输入说明&#xff1a;整数 N(N<10000)&#xff1b; 输出说明&#xff1a;符合条件的数的个数 输入样例&#xff1a;10 输出样例&#xff1a;3 (说明&#xff1a;样例中符合条件的3个数是…

一个比较特别的串口工具

这是08年写的一个 并网带电池逆变器 的通讯工具&#xff0c;和普通的串口调试器相比&#xff0c;多了一个【脚本】功能。能够通过【脚本】完成通讯测试。 PC发给DSP的01命令 01 10 1B 00 CF A3 00 00 90 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 电…

开源移动核心网Magma架构设计启示

Magma是由Meta Connectivity开发并开源给Linux基金会的开源移动核心网项目&#xff0c;目的是构建灵活、低成本、可扩展的移动核心网。本文介绍了Magma架构设计的基本理念和取舍。原文: Implications of the Magma Architecture: Interoperability, Scale and Resilience 简介 …

Steger算法实现结构光光条中心提取(python版本)

Steger算法原理 对结构光进行光条中心提取时,Steger算法是以Hessian矩阵为基础的。它的基础步骤如下所示: 从Hessian矩阵中求出线激光条纹的法线方向在光条纹法线方向上将其灰度分布按照泰勒多项式展开,求取的极大值即为光条在该法线方向上的亚像素坐标。对于二维离散图像来…

Java之JavaConfig

Java-JavaConfig 一&#xff0c;什么是JavaConfig 1.介绍 JavaConfig是一种用于配置Java应用程序的方法。它是Spring框架提供的一种替代XML配置的方式&#xff0c;旨在简化和增强应用程序的配置过程。 传统上&#xff0c;Spring框架使用XML文件来定义应用程序的配置信息&am…