C++:list

news2024/11/16 2:52:51

目录

List的模拟实现

List节点类

List链表结构

List迭代器类

结构

T& operator*();

T& operator->();

Self& operator++();

Self operator++(int);

Self& operator--();

Self& operator--(int);

bool operator!=(const Self& l);

bool operator==(const Self& l);

List的构造

构造函数

迭代器区间构造

拷贝构造

运算符重载

析构函数

List iterator

begin

end

List Capacity

size

empty

List Access

front

back

List Modify

在pos位置前插入值为val的节点

删除pos位置的节点

clear

其它功能进行复用


学习目标

1.会模拟实现list的基础功能

2.const迭代器(模板类的参数)

3.->的重载

List的模拟实现

List节点类

1.指针域         2.数据域

	//1,定义节点
	template<class T>
	struct list_node 
	{
		list_node<T>* _pre;
		list_node<T>* _next;
		T _data;

		//构造函数
		list_node(const T& x = T()) 
			:_pre(nullptr)
			,_next(nullptr)
			,_data(x)
		{}
	};

List链表结构

1.结构:双向带头循环链表

	//2.list(链表)
	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->_pre = _head;
			_head->_next = _head;
		}
	private:
		node* _head;
	};

List迭代器类

链表的成员都是节点,需要使用节点指针,于是不再使用原生指针,而对原生指针进行封装

1.迭代器要么是原生指针

2.迭代器要么是自定义类型对原生指针的封装,模拟指针的行为

(Vector中由于存储空间连续,指针ptr++就跳到下一个成员的位置 )

( List中,存储空间不是连续的,指针ptr++不一定会跳到下一个成员的位置)

结构

	//3.list的迭代器类
	template<class T, class Ref,class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> node;
		typedef __list_iterator<T, Ref,Ptr> self;
		node* pnode;

		//构造函数
		__list_iterator(node* n)
			:pnode(n)
		{}
    };

T& operator*();

		//*(解引用)
		Ref operator*()
		{
			return pnode ->_data;
		}


T& operator->();

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

Self& operator++();

		self& operator++() 
		{
			pnode = pnode->_next;
			return *this;
		}


Self operator++(int);

		self operator++(int) 
		{
			self tmp(*this);//拷贝构造
			pnode = pnode->_next;
			return tmp;
		}


Self& operator--();

		self& operator--() 
		{
			pnode = pnode->_pre;
			return *this;
		}


Self& operator--(int);

		self operator--(int)
		{
			self tmp(*this);
			pnode = pnode->_pre;
			return tmp;
		}


bool operator!=(const Self& l);

		bool operator==(const self& I) 
		{
			return pnode == I.pnode;
		}


bool operator==(const Self& l);

		bool operator!=(const self& I)
		{
			return pnode != I.pnode;
		}

List的构造

构造函数

		//构造函数
		void init()
		{
			_head = new node;
			_head->_pre = _head;
			_head->_next = _head;
		}

		list() 
		{
			_head = new node;
			_head->_pre = _head;
			_head->_next = _head;
		}
		
		list(int n, const T& value = T()) 
		{
			init();
			while (n--) 
			{
				push_back(value);
			}
		}

迭代器区间构造

		//迭代器区间构造
		template <class Iterator>
		list(Iterator first, Iterator last) 
		{
			init();
			while (first != last) 
			{
				push_back(*first);
				++first;
			}
		}

拷贝构造

		void swap(list<T>& L) 
		{
			std::swap(_head,L._head);
		}

		//拷贝构造(现代写法)
		list(const list<T>& L) 
		{
			init();

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

运算符重载

		//运算符重载(现代写法)
		list<T>& operator=(const list<T> L) 
		{
			swap(L);
			return *this;
		}

这里不加引用就是用其拷贝构造,若加了引用,赋值后改变这个list,L也会被改变

析构函数

		//析构函数
		~list() 
		{
			clear();
			delete _head;
			_head = nullptr;
		}

List iterator

迭代器

		//迭代器
		typedef __list_iterator<T, T&,T*> iterator;
		typedef __list_iterator<T, const T&,const T*> const_iterator;

begin

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

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

end

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

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

List Capacity

size

		size_t size()const 
		{
			size_t count = 0;
			const_iterator it = begin();
			while (it != end()) 
			{
				count++;
				++it;
			}
			return count;
		}

empty

		bool empty()const 
		{
			return _head->_next == _head;
		}

List Access

front

		T& front() 
		{
			return _head->_next->_data;
		}
		const T& front()const 
		{
			return _head->_next->_data;
		}

back

		T& back() 
		{
			return _head->_pre->_data;
		}
		const T& back()const 
		{
			return _head->_pre->_data;
		}

List Modify

头插,头删,尾插,尾删,在pos位置插入val,删除pos位置的节点并返回下一节点位置

clear,swap

在pos位置前插入值为val的节点

		iterator insert(iterator pos, const T& val) 
		{
			node* cur = pos.pnode;
			node* pre = cur->_pre;

			node* new_node = new node(val);
			pre->_next = new_node;//pos前的节点与new_node连接
			new_node->_pre = pre;
			new_node->_next = cur;//new_node与pos的节点连接
			cur->_pre = new_node;

			return new_node;
		}

删除pos位置的节点

返回该节点的下一个位置

		iterator erase(iterator pos) 
		{
			node* pre = pos.pnode->_pre;
			node* next = pos.pnode->_next;

			pre->_next = next;//连接pos的前后节点
			next->_pre = pre;

			delete pos.pnode;//删除pos位置的节点
			return next;
		}

clear

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

其它功能进行复用

		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位置插入值

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

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

相关文章

JDK、JRE 和 JVM 的区别和联系

三者关系 就这三者的关系而言&#xff0c;jvm是jre的子集&#xff0c;jre是jdk的子集&#xff0c;具体关系如下图&#xff1a; Java的执行流程 对于一个Java程序&#xff0c;其执行流程大致如下&#xff1a; 开发人员使用JDK编写和编译Java源代码&#xff0c;生成Java字节码文…

二叉树层序遍历及判断完全二叉树

个人主页:Lei宝啊 愿所有美好如期而遇 目录 二叉树层序遍历&#xff1a; 判断完全二叉树&#xff1a; 二叉树层序遍历&#xff1a; 层序遍历就是一层一层&#xff0c;从上到下遍历&#xff0c;上图遍历结果为&#xff1a;4 2 7 1 3 6 9 思路&#xff1a; 通过队列来实现层序…

lenovo联想笔记本电脑ThinkPad X13 AMD Gen2(20XH,20XJ)原装出厂Windows10系统镜像

联想原厂Win10系统&#xff0c;自带所有驱动、出厂主题壁纸、系统属性联想LOGO专属标志、Office办公软件、联想电脑管家等预装程序 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;dolg 适用于型号&#xff1a;20XL,20XJ,20XG,21A1,20XK,20XH,20XF,21A0 所需要…

1.vue3脚手架在vscode下面建立

一、下载安装node.js Node.js (nodejs.org) 二、安装vue3脚手架 #添加项目脚手架 npm install -g vue/cli 三、建立项目 #项目建立 vue create {appname} 测试项目安装成功&#xff1a;运行npm run serve命令 npm run serve 证明脚手架、项目环境已配置好 四、添加配件&#x…

5+非肿瘤+铁死亡+实验验证生信思路解析

今天给同学们分享一篇非肿瘤铁死亡实验验证的生信文章“Identification and validation of ferroptosis-related gene signature in intervertebral disc degeneration”&#xff0c;这篇文章于2023年2月6日发表在Front Endocrinol (Lausanne)期刊上&#xff0c;影响因子为5.2。…

Windows专业版的Docker下载、安装与启用Kubenetes、访问Kubernetes Dashboard

到Docker 官网https://www.docker.com/ 下载windows操作系统对应的docker软件安装 Docker Desktop Installer-Win.exe 2023-09版本是4.23 下载后双击安装 重启windows后&#xff0c;继续安装 接受服务继续安装 解决碰到的Docker Engine stopped 打开 控制面板》程序》启用或关…

Java-day15(Java常用类)

Java常用类 1.String类 public class test1 {/** String&#xff1a;代表不可变的字符序列&#xff0c;底层使用char[]存放* String是final的 * */Testpublic void test() {String str1 "Java EE";String str2 "Java EE";String str3 new String("…

用sublime测试正则表达式

1 打开sublime 2.使用ctrlf快捷键 3.开启如下功能 4.测试

什么是语法糖?Java中有哪些语法糖?

什么是语法糖&#xff1f;Java中有哪些语法糖&#xff1f; 语法糖 语法糖&#xff08;Syntactic Sugar&#xff09;&#xff0c;也称糖衣语法&#xff0c;是由英国计算机学家 Peter.J.Landin 发明的一个术语&#xff0c;指在计算机语言中添加的某种语法&#xff0c;这种语法对…

【操作系统笔记十三】Shell脚本编程

什么是 shell shell 就是命令解释器&#xff0c;用于解释用户对操作系统的操作&#xff0c;比如当我们在终端上执行 ls &#xff0c;然后回车&#xff0c;这个时候会由 shell 来解释这个命令&#xff0c;并且执行解释后的命令&#xff0c;进而对操作系统进行操作。 在 Centos…

初识软件工程

软件工程是一门涵盖软件开发、维护和管理的学科&#xff0c;它通过应用工程化的原则和方法来提高软件系统的质量和可靠性。在当今数字化和信息化的时代&#xff0c;软件工程对于现代社会的各个领域都具有至关重要的作用。 基本概念&#xff1f; 计算机系统中与硬件相互依存的一…

【力扣】300. 最长递增子序列 <动态规划>

【力扣】300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2…

Wiki.js - 下一代的开源Wiki软件

简介&#xff1a;在众多开源的Wiki软件中&#xff0c;Wiki.js无疑是一个独特且现代的选择。基于Node.js构建&#xff0c;使用了最新的Web技术&#xff0c;Wiki.js为用户提供了一个美观且功能丰富的界面&#xff0c;同时还保留了强大的扩展性和自定义性。无论你是为个人、团队或…

一文掌握CodiMD安装与使用

简介&#xff1a;CodiMD 是一个基于 Markdown 语言的实时协作文档编辑器&#xff0c;它允许多个用户在同一个文档上进行实时编辑。CodiMD 的前身是 HackMD&#xff0c;但为了满足更开放的开源社区需求&#xff0c;CodiMD 作为其社区版本独立出来。 优势&#xff1a; 1. 开源且…

9+单细胞+实验验证,探讨单基因对癌细胞转移作用的思路方向

今天给同学们分享一篇单细胞实验的生信文章“Identification of RAC1 in promoting brain metastasis of lung adenocarcinoma using single-cell transcriptome sequencing”&#xff0c;这篇文章于2023年5月18日发表在Cell Death Dis期刊上&#xff0c;影响因子为9。 本研究旨…

2023研究生数学建模E题保姆级思路 出血性脑卒中临床智能诊疗

本次E题是一道J机器学习题目&#xff0c;难度也比较高&#xff0c;该题一般是有正确结果的&#xff0c;容易踩坑&#xff0c;不太建议小白选择&#xff0c;小白可以选择D题&#xff0c;D题思路也可以看另一篇文章&#xff0c;总的难度都不算低&#xff0c;这三道的难度接近&…

科目三基础四项(一)

​ 第一天&#xff0c;基础操作&#xff0c;仪表&#xff0c;方向&#xff0c;挡位 按照模块来 1、方向盘两手在两侧 ​ 编辑 转向时的角度&#xff0c;只用&#xff1a;向左540&#xff0c;向右180 向左打和向右打的角度要抵消&#xff0c;回正 掉头向左打满再回 注意…

【LeetCode热题100】--56.合并区间

56.合并区间 排序&#xff1a; 如果按照区间的左端点排序&#xff0c;那么在排完序的列表中&#xff0c;可以合并的区间一定是连续的&#xff0c;如下图所示&#xff0c;标记为蓝色、黄色和绿色的区间分别可以合并为一个大区间&#xff0c;它们在排完序的列表中是连续的 算法&a…

Learn Prompt-Midjourney 图片生成:快速开始

Discord 注册​ Midjourney 目前是在 Discord 频道上运行。我们可以通过 Discord 的机器人进行指令操作&#xff0c;最终返回图片。 我们可以直接点击进入Midjourney Discord频道。当然如果你直接搜索进入Midjourney的官网&#xff0c;你同样可以通过点击右下角的绿色按钮Joi…

vuepress+gitee免费搭建个人在线博客(无保留版)

文章目录 最终效果&#xff0c;一睹为快&#xff01;一、工具选型二、什么是VuePress三、准备工作3.1 node 安装3.2 Git安装3.3 Gitee账号注册 四、搭建步骤4.1 初始化VuePress4.2 安装VuePress4.3 初始化目录4.4 编写文章 五、部署到Gitee5.1 创建仓库5.2 个人空间地址设置4.3…