C++中list的模拟实现

news2024/10/5 13:33:40

目录

1.结构

2.用3个类实现list

3.单个节点的定义

4.迭代器的定义

5.list类的实现

6.vector与list的区别


1.结构

list底层是一个带头双向循环链表

2.用3个类实现list

1.链表中的单个节点

2.迭代器

3.list

由于链表中的迭代器已经不是原生指针,所以将迭代器单独封装成一个类。

list的迭代器是双向迭代器,不能够像string和vector那样的随机迭代器那样可以+3 -3,只能够++和--

3.单个节点的定义

template<class T>
class listnode
{
public:
    T _data;
    listnode<T>* _prev;
    listnode<T>* _next;

    listnode(const T& x = T())
        :_data(x)
        ,_prev(nullptr)
        ,_next(nullptr)
    {}

};

4.迭代器的定义

//Ref是T的引用但不知道是不是const迭代器,所以写成模版的形式
//Ptr是T的指针但不知道是不是const迭代器,所以写成模版的形式
//这样就不用单独写一个const迭代器了
template<class T, class Ref, class Ptr>
class list_iterator
{
public:
    typedef listnode<T> Node;
	typedef list_iterator<T, Ref, Ptr> Self;

    Node* _node;


	//这里的构造函数是为了一会方便提供list类里的begin和end的接口
	//begin和end接口写在list类里是因为:在List类里才有真正的链表结构
	list_iterator(Node* node)
		:_node(node)
	{}

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

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

	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;
	}

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

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



};

5.list类的实现

template<class T>
class List
{
    typedef listnode<T> Node;
	
public:

	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;
        _size = 0;
    }

	iterator begin()
	{
		//隐式类型转换,利用迭代器类里的构造函数
		return _head->next;
	}

	iterator end()
	{
		//隐式类型转换
		return _head;
	}

	const_iterator begin() const
	{
		//隐式类型转换
		return _head->next;
	}

	const_iterator end() const
	{
		//隐式类型转换
		return _head;
	}

	void push_back(const T& x)
	{
		/*Node* newnode = new Node(x);
		Node* prev = _head->_prev;
		Node* cur = _head;
		newnode->_prev = prev;
		newnode->_next = cur;
		prev->_next = newnode;
		cur->_prev = newnode;*/

		insert(end(), x);
	}

	void insert(iterator pos, const T& x)
	{
		Node* prev = pos->_prev;
		Node* cur = pos;
		Node* newnode = new Node(x);
		newnode->_prev = prev;
		newnode->_next = cur;
		prev->_next = newnode;
		cur->_prev = newnode;
		_size++;
	}


	//返回被删除元素的下一个元素的迭代器,防止迭代器失效
	iterator erase(iterator pos)
	{
		Node* prev = pos->_prev;
		Node* next = pos->_next;
		prev->_next = next;
		next->_prev = prev;
		delete pos;
		_size--;
		return next;
	}

	//拷贝构造
	List(const List<T>& s1)
	{
		_head = new Node;
		_head->prev = _head;
		_head->next = _head;
		_size = 0;

		for (auto s : s1)
		{
			push_back(s);
		}

	}

	void swap(List<T> sl)
	{
		std::swap(_head, sl._head);
		std::swap(_size, sl._size);
	}



	List<T>& operator=(List<T> s1)
	{
		swap(s1);
		return *this;
	}

	void clear()
	{
		iterator it = begin();
		while (it != end())
		{
			it = erase(it);
		}
	}

	~List()
	{
		clear();
		delete _head;
		_head = nullptr;

	}


	int size() const
	{
		return _size;
	}

	bool empty() const
	{
		return _size == 0;
	}


private:
    Node* _head;
    int _size;
};

6.vector与list的区别

vector中没有支持头插和头删的接口,但是可以调用insert接口间接头插头删

list中有支持头插头删的接口

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

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

相关文章

针对线上消息积压的排查思路以及解决方案

一、背景 我们在日常工作中&#xff0c;经常会碰到线上告警&#xff0c;消息队列消息积压了&#xff0c;试想如果对消息的消费速率有要求的场景&#xff0c;消息积压一定会或多或少对自己本身的业务场景有影响&#xff0c;这里就针对消息积压的场景&#xff0c;谈谈具体的排查…

过滤器Filter【详解】

过滤器Filter 1、 现有问题 在以往的Servlet中&#xff0c;有冗余的代码&#xff0c;多个Servlet都有重复的代码 比如编码格式设置 登录信息认证 2、 概念 过滤器&#xff08;Filter&#xff09;是处于客户端与服务器目标资源之间的一道过滤技术。 过滤器 3、 过滤器作用 执…

Python办公自动化教程(006):Word添加标题

2.3 word标题 介绍&#xff1a; 在 python-docx 中&#xff0c;您可以使用 add_heading() 方法为文档添加标题。此方法允许您指定标题的文本和级别&#xff08;例如&#xff0c;一级标题、二级标题等&#xff09;。标题级别的范围是从 0 到 9&#xff0c;其中 0 表示文档的主标…

深度解析:从浏览器输入链接到页面展现的奇幻历程

〇、前言 当我们在浏览器中输入一个网址&#xff0c;例如&#xff1a;example.com&#xff0c;按下回车键后&#xff0c;会发生什么呢&#xff1f; 主要会发生以下这些过程&#xff1a;域名解析、建立HTTP连接、发送HTTP请求、数据传输、渲染网页、断开HTTP连接。 一、域名解…

类型转换【C++提升】(隐式转换、显式转换、自定义转换、转换构造函数、转换运算符重载......你想知道的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 座右铭&#xff1a;梦想是一盏明灯&#xff0c;照亮我们前行的路&#xff0c;无论风雨多大&#xff0c;我们都要坚持不懈。 一…

【srm系统】供应商管理,招投标管理,电子采购系统,询价管理

前言&#xff1a; 随着互联网和数字技术的不断发展&#xff0c;企业采购管理逐渐走向数字化和智能化。数字化采购平台作为企业采购管理的新模式&#xff0c;能够提高采购效率、降低采购成本、优化供应商合作效率&#xff0c;已成为企业实现效益提升的关键手段。系统获取在文末…

[含文档+PPT+源码等]精品基于Python实现的美术馆网站的设计与实现

基于Python实现的美术馆网站&#xff0c;其设计与实现背景主要源于以下几个方面的需求和发展趋势&#xff1a; 一、文化艺术领域的发展需求 随着文化娱乐活动的日益丰富&#xff0c;美术馆作为展示艺术作品、传播文化的重要场所&#xff0c;其管理和服务模式的创新对于提升公…

LabVIEW提高开发效率技巧----使用动态事件

在LabVIEW开发过程中&#xff0c;用户交互行为可能是多样且不可预知的。为应对这些变化&#xff0c;使用动态事件是一种有效的策略。本文将从多个角度详细介绍动态事件的概念及其在LabVIEW开发中的应用技巧&#xff0c;并结合实际案例&#xff0c;说明如何通过动态事件提高程序…

【售后资料】软件售后服务方案(word原件)

软件售后服务方案的售后服务范围广泛&#xff0c;涵盖了多个方面&#xff0c;以确保客户在使用软件过程中得到全面、及时的支持。具体来说&#xff0c;这些服务范围通常包括以下几个核心内容&#xff1a; 技术支持服务维护与更新服务培训与教育服务定制化服务数据管理与服务客户…

如何获取网页内嵌入的视频?

如何获取网页内嵌入的视频&#xff1f; 有时插件无法识别的视频资源&#xff0c;可以通过手动使用浏览器的开发者工具来抓取。你可以按照以下步骤操作&#xff1a; 步骤&#xff1a; 打开网页并按 F12&#xff1a;在视频页面按下 F12 或右键点击网页并选择“检查”或“Inspe…

Spring Boot实现的大学生就业市场解决方案

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

【案例】距离限制模型透明

开发平台&#xff1a;Unity 2023 开发工具&#xff1a;Unity ShaderGraph   一、效果展示 二、路线图 三、案例分析 核心思路&#xff1a;计算算式&#xff1a;透明值 实际距离 / 最大距离 &#xff08;实际距离 ≤ 最大距离&#xff09;   3.1 说明 | 改变 Alpha 值 在 …

简易投影仪的制作

今天不做开发类的文章&#xff0c;来给大家整个活哈哈哈哈哈。由于前几天室友说看小屏幕的抖音太不舒服&#xff0c;比较累眼睛&#xff0c;所以我萌生出来一个制作投影仪的想法。于是查阅了资料最终完成以下的设计。 以下设计价格最高的是一部旧的可拆卸的智能手机 简易投影仪…

C++11新特性(基础)【2】

目录 1.范围for循环 2.智能指针 3.STL中一些变化 4.右值引用和移动语义 4.1 左值引用和右值引用 4.2 左值引用与右值引用比较 4.3 右值引用使用场景和意义 4.4 右值引用引用左值及其一些更深入的使用场景分析 4.5 完美转发 1.范围for循环 int main() {int array[10] { 1,2,3,4…

CSS | CSS中强大的margin负边距

css中的负边距(negative margin)是布局中的一个常用技巧&#xff0c;只要运用得合理常常会有意想不到的效果。很多特殊的css布局方法都依赖于负边距&#xff0c;所以掌握它的用法对于前端的同学来说&#xff0c;那是必须的。本文非常基础&#xff0c;老鸟可以略过。 一、负边距…

【宽搜】3. leetcode 515 在每个树行中找最大值

1 题目描述 题目链接&#xff1a;在每个树行中找最大值 2 题目解析 根据题目描述&#xff0c;是找出每一行中的最大值&#xff0c;这毋庸置疑是使用宽度优先遍历了。我在这篇文章中讲解了宽度优先遍历的模板&#xff0c;如果没有看的同学可以先去看一下。 这道题和模板的不…

基于微信小程序的调查问卷管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

数据结构与算法(七)静态链表

目录 前言 一、静态链表的引入 二、线性表的静态链表存储结构 三、静态链表的插入操作 四、静态链表的删除操作 五、静态链表的优缺点总结 1、优点 2、缺点 3、小结 六、单链表小结——Tecent面试题 1、普通解法&#xff1a; 2、高级解法&#xff1a; 前言 静态链表…

基于CAN总线的TMS320F28335 Bootloader设计说明

1 设计目的 根据客户要求&#xff0c;开发一款基于CAN总线的TI公司TMS320F28335 DSP&#xff08;数字信号处理器&#xff09;bootloader&#xff0c;以方便应用程序的刷写。CAN设备采用周立功CAN卡&#xff08;USBCAN-I、USBCAN-II、USBCAN-E-mini&#xff09;。 2 专有信息 …

一篇文章吃透OA系统

一、OA系统是什么&#xff0c;都有什么功能&#xff1f; OA系统&#xff08;Office Automation System&#xff09;是办公自动化系统的简称&#xff0c;是一种利用计算机技术和网络通信技术&#xff0c;为企业和组织提供办公管理和协作支持的信息化系统。OA系统旨在提高办公效…