C++的List

List的使用

构造

与vector的区别

与vector的区别在于不支持 [ ]

由于链表的物理结构不连续,所以只能用迭代器访问

vector可以排序,list不能排序(因为快排的底层需要随机迭代器,而链表是双向迭代器)

(算法库里的排序不支持)(需要单独的排序)

list存在vector不支持的功能

链表的排序

vector可以用算法库里的sort排序,list不能用算法库里的sort排序排序(因为快排的底层需要随机迭代器,而链表是双向迭代器)

(算法库里的排序不支持)(需要单独的排序)

链表的排序效率要远低于算法库里的快排,因此链表的sort很少使用

即使将list拷贝会vector排序再拷贝回来,效率依旧大于直接在list中排序

升序

降序

去重(unique)

去除多个重复的数据,每个值只留一个

但是去重有一个前提,需要先排序,否则去不全

迭代器访问链表

list的剪切

将一个链表的内容转移(剪切)到另一个链表

也可以自己剪切自己,来把某个节点向前或后移动

list变为"3 1 2 4"

List的实现(双向带头循环)

链表基础结构

_head是双向带头循环链表的哨兵位(不存储有效数据)

list的迭代器

与vector不同,list在物理上是不连续的

因此不能像vector一样

因为这样++iterator不能得到下一个节点

因此可以选择建立一个类来进行封装

可以在该类中重载 " ++ " 和 " * "等运算符

是迭代器可以实现作用

但是注意不需要重载 " + "和 " - "  ,因为他们的效率很低

同时,迭代器类不需要写析构函数

因为节点不属于迭代器,只是需要用迭代器访问

节点是属于链表的

也不需要写拷贝构造(深拷贝),默认生成的浅拷贝就够了

因为没有写析构,所以也不存在析构两次的问题

->的重载

迭代器内还重载了 " -> "运算符

eg.

对于自定义类型

想要进行输出,又没有重载>>符号

方法一

比较原始的方法:

方法二

这里就是重载了 " -> "符号

从逻辑上讲

方法2应该有两个->,但是为了代码的可读性,省略了一个->

const迭代器

采用引用传参一般会给参数加const,就产生了const迭代器

但是注意

所以需要单独写一个类,让迭代器可以修改,但它指向的内容不能修改(控制返回值)

该类与之前写的迭代器的类非常相似,唯一的区别就是operator* 和operator->的返回值不同

迭代器不能修改的核心行为是operator* 和operator->

控制operator* 和operator->的返回值,从而达成不能修改的目的

但是,以上两个类重复度很高,重写一个类过于浪费

因此可以采取新添加两个模板参数

写一个类模板,传不同的模板参数,来控制返回值

这样相当于利用模板生成了两个类,交给编译器来完成

提高了开发效率

插入insert

链表里的insert不存在迭代器失效的问题,因为它不存在扩容

pos指向的位置也不会变

删除erase

erase存在迭代器失效的问题

是野指针失效

拷贝

默认的浅拷贝存在一定的问题

eg.

因为浅拷贝,指向同一块空间,会相互影响,析构两次

析构函数

这里用clear()清除数据

深拷贝

在范围for时,如果不确定遍历的类型,最好加引用&

赋值

直接交换两个链表的头节点就行

因为传入的参数不是引用,lt是lt3的临时拷贝,使用完后就会释放

交换头节点后,不仅实现了赋值,还顺便将原链表析构了

initializer_list

为了支持{ }赋值,需要写一个initializer_list

参数不用加引用&

因为initializer_list直接用{ }初始化,里面是常量数组

里面是直接用指针指向常量数组的开始和结束

模拟实现

#pragma once
#include <iostream>
using namespace std;
namespace bit
{template<class T>struct ListNode//定义一个链表节点的结构体//因为结构体内的东西全部公有,所以选择结构体,而不是类//一个类有公有私,用class,全部公有,用struct{ListNode<T>* _next;ListNode<T>* _prev;//结构体指针后加<T>模板,否则结构体指针就无法指向该类型的数据T _data;ListNode(const T& data = T())//初始化: _next(nullptr), _prev(nullptr), _data(data)//初始化列表{}};template<class T, class Ref, class Ptr>class ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;public://++itListIterator(Node* node):_node(node){}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;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self& it){return _node != it._node;}};//template<class T>//class ListConstIterator//{//	typedef ListNode<T> Node;//	typedef ListConstIterator<T> Self;//	Node* _node;//public://	//++it//	ListIterator(Node* node)//		:_node(node)//	{}//	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;//	}//	const T& operator*()//	{//		return _node->_data;//	}//	const T* operator->()//	{//		return &_node->_data;//	}//	bool operator!=(const Self& it)//	{//		return _node != it._node;//	}//};template<class T>class list//链表{typedef ListNode<T> Node;public:typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&,const  T*> const_iterator;/*	typedef ListConstIterator<T> const_iterator;*/iterator begin(){return iterator(_head->_next);//传入匿名对象构造一个iterator类型的变量来返回}iterator end(){return iterator(_head);}void empty_init(){_head = new Node();_head->_next = _head;_head->_prev = _head;}list(){/*_head = new Node(T());_head->_next = _head;_head->_prev = _head;*/empty_init();} list(initializer_list<T> il){for (const auto& e : il){push_back(e);}}//lt2(lt1)list(const list<T>& It)//深拷贝构造{empty_init();for (const auto& e : lt){push_back(e);}}//lt1 = lt3list<T>& operator=(list<T> lt){swap(_head, lt._head);return *this;}~list(){clear();delete _head;_head = nullptr;}void clear(){auto it = begin();while (it != end()){it = erase(it);}}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->_prev = newnode;}void insert(iterator pos, const T& x){Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;return iterator(newnode);}void erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return iterator(next);}private:Node* _head;};void test_list1(){list<int> It1;It1.push_back(1);It1.push_back(2);It1.push_back(3);It1.push_back(4);list<int>::iterator it = It1.begin();while (it != It1.end()){*it += 10;cout << *it << " ";++it;}cout << endl;}
}

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

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

相关文章

网站建设方案书

网站建设方案书是指一份书面计划&#xff0c;用于描述关于建立和运营一个网站所需的资源和步骤。这份方案书的目的是确保网站建设过程中的顺利和成功&#xff0c;并最终获得对其所期望的效果。 在撰写方案书时&#xff0c;我们应该遵循以下几个步骤&#xff1a; 一、确定网站的…

[SWPUCTF 2023 秋季新生赛]Junk Code

方法一&#xff1a;手动去除 将所有E9修改为90即可 方法二&#xff1a;花指令去除脚本 start_addr 0x0000000140001454 end_addr 0x00000001400015C7 print(start_addr) print(end_addr) for i in range(start_addr,end_addr):if get_wide_byte(i) 0xE9:patch_byte(i,0x9…

自定义类型:结构体类型

在学习完指针相关的知识后将进入到c语言中又一大重点——自定义类型&#xff0c;在之前学习操作符以及指针时我们对自定义类型中的结构体类型有了初步的了解&#xff0c;学习了结构体类型的创建以及如何创建结构体变量&#xff0c;还有结构体成员操作符的使用&#xff0c;现在我…

win+mac通用的SpringBoot+H2数据库集成过程。

有小部分大学的小部分老师多毛病&#xff0c;喜欢用些晦涩难搞的数据库来折腾学生&#xff0c;我不理解&#xff0c;但大受震撼。按我的理解&#xff0c;这种数据库看着好像本地快速测试代码很舒服&#xff0c;但依赖和数据库限制的很死板&#xff0c;对不上就是用不了&#xf…

Linux基础之进程等待

目录 一、进程等待的基本概念 二、进程等待的重要性 三、进程等待的方法 四、获取子进程status 五、options选项 一、进程等待的基本概念 进程等待是指一个进程在执行过程中暂时停止&#xff0c;并等待某个条件满足后再继续执行的状态。这种等待通常是由于某些事件需要发生…

qt按钮的autoRepeat属性和default属性

autoRepeat属性&#xff1a;按住按钮不松&#xff0c;表示一直在点击按钮 default属性&#xff1a;点击Enter键表示在点击按钮

无缝接入GPT-4o:智创聚合API平台的创新与实践

在2024年5月13日&#xff0c;美国开放人工智能研究中心&#xff08;OpenAI&#xff09;发布了最新版本的ChatGPT——GPT-4o。这一更新标志着人工智能领域的又一重大进步&#xff0c;引起了全球科技界的广泛关注。GPT-4o的“o”代表“omni”&#xff08;全能&#xff09;&#x…

动态规划算法:背包问题

背包问题概述 背包问题 (Knapsack problem) 是⼀种组合优化的 NP完全问题 。 问题可以描述为&#xff1a;给定⼀组物品&#xff0c;每种物品都有⾃⼰的重量和价格&#xff0c;在限定的总重量内&#xff0c;我们如何选择&#xff0c;才能使得物品的总价格最⾼。 根据物品的个…

【刷题】初探递归算法 —— 消除恐惧

送给大家一句话&#xff1a; 有两种东西&#xff0c; 我对它们的思考越是深沉和持久&#xff0c; 它们在我心灵中唤起的惊奇和敬畏就会日新月异&#xff0c; 不断增长&#xff0c; 这就是我头上的星空和心中的道德定律。 -- 康德 《实践理性批判》 初探递归算法 1 递归算…

AI预测体彩排3采取888=3策略+和值012路一缩定乾坤测试6月2日预测第9弹

今天继续基于8883的大底进行测试&#xff0c;今天继续测试&#xff0c;好了&#xff0c;直接上结果吧~ 首先&#xff0c;888定位如下&#xff1a; 百位&#xff1a;5,4,7,3,2,9,1,0 十位&#xff1a;4,6,5,7,2,9,1,0 个位&#xff1a;3,4,2,5,…

车流量智能监测识别摄像机

车流量智能监测识别摄像机是一项革命性的技术&#xff0c;正在为城市交通管理带来巨大改变。这种摄像机利用先进的人工智能和图像识别技术&#xff0c;能够实时监测道路上的车流量&#xff0c;并对车辆进行智能识别和分类&#xff0c;从而实现对交通流量的精准监测和管理。 与传…

Day02 设计首页导航条

设计首页导航条 导航条的样式&#xff0c;主要是从Material DesignThemes UI 拷贝过来修改的,项目用了这个UI组件库。就看项目需要什么&#xff0c;就去源码拷过来使用。 直接下载源码&#xff0c;编译运行就可以看到Demo 了 下载后且正常编译成功了&#xff0c;是能正常跑起来…

iOS——类与对象底层探索

类和对象的本质 当我们使用OC创建一个testClass类并在main函数创建它的实例对象的时候&#xff0c;OC的底层到底是什么样的呢&#xff1f; 首先&#xff0c;我们要了解OC对象的底层结构&#xff0c;那么我们就得知道&#xff1a;OC本质底层实现转化其实都是C/C代码。 使用下面…

spoon工具的常用基础操作

一些常用转换工具 1、emp表输入->excel表输出 emp表输入&#xff0c;可以进行预览查看数据有没有过来excel表输出 成功执行后&#xff0c;可以到保存的excel位置进行查看。 2、excel输入->表输出 运行转换后可以在oracle进行查看是否有成功创建这个表 3、对部门最高…

【JAVA WEB实用与优化技巧】Maven自动化构建与Maven 打包技巧

文章目录 一、MavenMaven生命周期介绍maven生命周期命令解析 二、如何编写maven打包脚本maven 配置详解setting.xml主要配置元素setting.xml 详细配置 使用maven 打包springboot项目maven 引入使用package命令来打包idea打包 三、使用shell脚本自动发布四、使用maven不同环境配…

【协议开发系列】梳理关于TCP和UDP两种协议的区别和使用场景

起源 前二天项目上在核对外部对接服务的五元组列表的时候&#xff0c;有一位客户提问对于同样的服务同时支持tcp和udp二种方式&#xff0c;有什么优点和缺点&#xff0c;应该如何选择&#xff1f;这个问题突然让我愣了一下&#xff0c;确实好久没有“温故”了&#xff0c;相关…

商业新闻|当我们在讨论卖车时我们在讨论什么?

‍‍今天是2024年第22周 这是Yura「输出倒逼输入」计划的第10篇文章 全年进度&#xff1a;10/52 01 投资人为什么不断入局烧钱又亏损的新能源&#xff1f; 造车的烧钱速度超乎想象。除了最近的小米&#xff0c;这些年国内大大小小的玩家好像都在以不同的形式或直接或间接的参与…

【视频创作思维流程】教你从0培养视频创作思维

【视频创作思维流程】教你从0培养视频创作思维 1.创作认知2.培养自己的想象力2.1通过音乐辅助闭上眼睛想象2.2多看多见多模仿 3 视频脚本3.1简单的脚本3.2复杂脚本 4.拍摄预见能力4.1拍摄预见力思维用于转场4.2拍摄预见力思维给特效制作留住空间4.2拍摄预见力思维给字幕制作留住…

src挖掘-记一次付费资源的sign绕过

0x01 前言 最近都没怎么挖到过细小的漏洞&#xff0c;一直纠结于一些比较难以实现的点&#xff0c;天天在各种测试、上线服务器里面fuzz找遗漏的点(bushi) 大概上周突破了一处付费资源免费调用&#xff0c;定级了&#xff0c;故发出来水水文 0x02 绕过过程 逛着逛着主站&…

五种最新算法求解柔性作业车间调度问题(Flexible Job Shop Scheduling Problem,FJSP),提供MATLAB代码

一、WSA求解FJSP FJSP&#xff1a;波搜索算法(Wave Search Algorithm, WSA)求解柔性作业车间调度问题&#xff08;FJSP&#xff09;&#xff0c;提供MATLAB代码-CSDN博客 二、SBOA求解FJSP FJSP&#xff1a;蛇鹫优化算法&#xff08;Secretary bird optimization algorithm&a…