关于list

1、什么是list

list是一个带头结点的双向循环链表模版容器,可以存放任意类型,需要显式定义

2、list的使用

有了前面学习string和vector的基础,学习和使用list会方便很多,因为大部分的内容依然是高度重合的。

与顺序表不同,链表是以结点形式进行链接和存储,其地址并不是连续的,因此进行插入和删除操作不需要进行大量的数据挪动,只需要改变指针的指向即可,方便很多。

使用push_back()和push_front()可以分别实现尾插和头插

    list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_front(5);lt.push_front(6);for (auto e : lt){cout << e << " ";}cout << endl;

也可以使用insert实现在某一位置的插入,erase实现在某一位置的删除

    lt.insert(lt.begin(), 9);for (auto e : lt){cout << e << " ";}cout << endl;lt.erase(lt.begin());for (auto e : lt){cout << e << " ";}cout << endl;

然而由于迭代器的失效问题,erase会返回被删除元素的下一个位置,因此,当进行连续删除时,我们可以使用迭代器来直接对此返回值进行接收来实现

	list<int>::iterator it = ++lt.begin();while (it != lt.end()){cout << (*it) << " ";it=lt.erase(it);}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;

同时,由于list底层结构的不同,不能像string和vector一样去实现迭代器,因为string和vector在底层结构中是连续的,可以直接用指针去访问得到相应位置的元素内容,对指针进行++或者--操作又可以直接到达下一位置或者前一位置,list中存放的是一个一个不连续的结点,对迭代器的实现时需要进行相应的重载,使用也会受限,比如在上述代码中就无法使用lt.begin()+3等,更多内容在进行list的模拟实现中可以得到更多的体会

reverse()用于逆置,库里有实现公用的reverse,不过list里面也有提供自己的逆置,如果使用公用的则需要使用两个参数指定逆置的范围,如果使用的是自己的逆置则不需要传参

    reverse(lt.begin(), lt.end());lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;

对于排序,之前的vector可以直接调用库中的sort()函数实现排序,实际sort()排序使用的是快排进行排序,而对于数组这种结构来说快排会很方便,而对于链表来说则比较困难,代价较高,因此库中的排序函数并不能对list进行排序,list内部自己有实现一个排序,可以进行使用并完成排序。不过对于list来说,排序始终代价较大,如果需要频繁使用排序应该使用其他的结构来存放数据,所以库里的sort()函数实质上也是对程序员的一种约束。

	//sort(lt.begin(), lt.end());lt.sort();for (auto e : lt){cout << e << " ";}cout << endl;

find()函数是库里实现的公用函数,list也可以使用,同时会返回寻找元素的位置

	auto it=find(lt.begin(), lt.end(), 3);cout << *it;

splice()可以用于将某一部分的内容转移至其他list中,也可以转移给自身的其他地方

	list<int> lt2 = { 10,20,30 };//全部转移//lt2.splice(lt2.begin(), lt);//部分转移//lt2.splice(lt2.begin(), lt, ++lt.begin());//转移某一位置的内容lt2.splice(lt2.begin(), lt,++lt.begin(),--lt.end());//转移某一段位置的内容//lt2.splice(++lt2.begin(), lt2, lt2.begin(), lt2.end());for (auto e : lt){cout << e << " ";}cout << endl;for (auto e : lt2){cout << e << " ";}cout << endl;lt2.splice(lt2.begin(), lt2, ++lt2.begin(), lt2.end());for (auto e : lt2){cout << e << " ";}cout << endl;

以上就是list的一些较常用的使用,那么在对list及其使用都有了解后就可以进行模拟实现

3、list的模拟实现

不得不说,我觉得list的实现比前面的string和vector的实现难很多,主要是迭代器的原因会上很大难度,很难以理解,所以直到勉强实现出来以后也还是处于一个似懂非懂的状态里,希望后面能继续加强自己的技术,实现轻松手撕

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;namespace bit
{template<class T>struct ListNode{ListNode(const T& val = T()):_prev(nullptr),_next(nullptr),_val(val){}ListNode* _prev;ListNode* _next;T _val;};template<class T,class Ref,class Ptr>struct List_iterator{typedef ListNode<T> Node;typedef List_iterator<T, Ref,Ptr> Self;Node* _node;List_iterator(Node* node):_node(node){}Ref operator*(){return _node->_val;}Ptr operator->(){return &_node->_val;}Self& operator++(){_node = _node->_next;return *this;}Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self& operator--(){_node = _node->_prev;return *this;}Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}bool operator!=(const Self& it){return _node != it._node;}bool operator==(const Self& it){return _node == it._node;}};template<class T>class List{public:typedef ListNode<T> Node;typedef List_iterator<T, T&, T*> iterator;typedef List_iterator<T, const T&, const T*> const_iterator;iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const {return _head->_next;}const_iterator end() const{return _head;}List(){empty_init();}//list(const list<T>& lt)//{//	empty_init();//	for (auto& e : lt)//	{//		push_back(e);//		_size++;//	}//}size_t size(){return _size;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_head->_val = 0;_size = 0;}void push_back(const T& x){insert(end(), x);//Node* newnode = new Node;//_head->_prev->_next = newnode;//newnode->_prev = _head->_prev;//newnode->_next = _head;//_head->_prev = newnode;//newnode->_val = x;//_size++;}void push_front(const T& x){insert(++end(), x);//Node* newnode = new Node;//_head->_next->_prev = newnode;//newnode->_next = _head->_next;//_head->_next = newnode;//newnode->_prev = _head;//newnode->_val = x;//_size++;}void pop_back(){erase(--end());}void pop_front(){erase(++end());}void clear(){iterator it = begin();while (it != end()){it = erase(it);}_size = 0;}iterator insert(iterator pos,const T& x){Node* newnode = new Node;Node* cur = pos._node;newnode->_prev = cur->_prev;cur->_prev->_next = newnode;cur->_prev = newnode;newnode->_next = cur;newnode->_val = x;_size++;return newnode;}iterator erase(iterator pos){Node* cur = pos._node;cur->_next->_prev = cur->_prev;cur->_prev->_next = cur->_next;pos._node = cur->_next;delete cur;_size--;return pos;}void swap(List<T> tmp){std::swap(_head, tmp._head);std::swap(_size, tmp._size);}List<T>& operator=(List<T> tmp){swap(tmp);return *this;}List(const List<T>& lt){empty_init();//const_iterator it = lt.begin();//while (it != lt.end())//{//	push_back(*(it));//	it++;//}//_size = lt._size;for (auto& e : lt){push_back(e);}}~List(){clear();delete _head;_head = nullptr;}private:Node* _head;size_t _size;};
}

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

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

相关文章

Mysql 查看当前事务锁

在 MySQL 中查看事务锁&#xff08;锁等待、锁持有等&#xff09;&#xff0c;可以使用以下方法&#xff1a; 一、查看当前锁等待情况&#xff08;推荐&#xff09; SELECTr.trx_id AS waiting_trx_id,r.trx_mysql_thread_id AS waiting_thread,r.trx_query AS waiting_query,b…

【Keil5-map文件】

Keil5-map文件■ map文件■ map文件

k8s 基本架构

基于Kubernetes(K8s)的核心设计&#xff0c;以下是其关键基本概念的详细解析。这些概念构成了K8s容器编排系统的基石&#xff0c;用于自动化部署、扩展和管理容器化应用。### 一、K8s核心概念概览 K8s的核心对象围绕容器生命周期管理、资源调度和服务发现展开&#xff0c;主要包…

Bell不等式赋能机器学习:微算法科技MLGO一种基于量子纠缠的监督量子分类器训练算法技术

近年来&#xff0c;量子计算&#xff08;Quantum Computing&#xff09; 和 机器学习&#xff08;Machine Learning&#xff09; 的融合成为人工智能和计算科学领域的重要研究方向。随着经典计算机在某些复杂任务上接近计算极限&#xff0c;研究人员开始探索量子计算的独特优势…

Edge浏览器设置网页自动翻译

一.浏览网页自动翻译设置->扩展->获取Microsoft Edge扩展->搜索“沉浸式翻译”->获取 。提示&#xff1a;如果采用其他的翻译扩展没找自动翻译功能&#xff0c;所以这里选择“沉浸式翻译”二.基于Java WebElement时自动翻译Java关键代码&#xff1a;提示&#xff1…

TCP/UDP协议深度解析(四):TCP的粘包问题以及异常情况处理

&#x1f50d; 开发者资源导航 &#x1f50d;&#x1f3f7;️ 博客主页&#xff1a; 个人主页&#x1f4da; 专栏订阅&#xff1a; JavaEE全栈专栏 本系列往期内容~ TCP/UDP协议深度解析&#xff08;一&#xff09;&#xff1a;UDP特性与TCP确认应答以及重传机制 TCP/UDP协议深…

R 基础语法

R 基础语法 R 语言是一种针对统计计算和图形表示而设计的编程语言&#xff0c;广泛应用于数据分析、统计学习、生物信息学等领域。本文将为您介绍 R 语言的基础语法&#xff0c;帮助您快速入门。 1. R 语言环境搭建 在开始学习 R 语言之前&#xff0c;您需要安装并配置 R 语言环…

语义熵怎么增强LLM自信心的

语义熵怎么增强LLM自信心的 一、传统Token熵的问题(先理解“痛点”) 比如模型回答“阿司匹林是否治疗头痛?”→ 输出“是” 传统Token熵:只看“词的概率”,比如“是”这个词的概率特别高(Token熵0.2,数值低说明确定性强 )。 但实际风险:医学场景里,“是”的字面肯定…

javaweb的几大常见漏洞

CTF javaweb中几大常见漏洞(基于java-security靶场) 对于CTF而言&#xff0c;java类型的题目基本都是白盒代码审计&#xff0c;在java类型的web题目增长的今天&#xff0c;java代码审计能力在ctf比赛中尤为重要。 这篇博客主要是给大家介绍一下一些常见漏洞在java代码里面大概是…

【设计模式C#】外观模式(用于解决客户端对系统的许多类进行频繁沟通)

一种结构性设计模式。特点是将复杂的子系统调用逻辑封装到一个外观类&#xff0c;从而使客户端更容易与系统交互。优点&#xff1a;简化了接口的调用&#xff1b;降低了客户端与子系统的耦合度&#xff1b;封装了子系统的逻辑。缺点&#xff1a;引入了额外的类&#xff0c;可能…

【PTA数据结构 | C语言版】二叉堆的快速建堆操作

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个顺序存储的数据用快速建堆操作调整为最小堆&#xff1b;最后顺次输出堆中元素以检验操作的正确性。 输入格式&#xff1a; 输入首先给出一个正整数 c&#xff08;≤1…

【数据结构初阶】--双向链表(二)

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

vue-cli 模式下安装 uni-ui

目录 easycom 自定义easycom配置的示例 npm安装 uni-ui 准备 sass 安装 uni-ui 注意 easycom 传统vue组件&#xff0c;需要安装、引用、注册&#xff0c;三个步骤后才能使用组件。easycom将其精简为一步。 只要组件路径符合规范&#xff08;具体见下&#xff09;&#…

JavaSE-接口

概念在Java中&#xff0c;接口可以被看成是一种公共规范&#xff0c;是一种引用数据类型。语法1.接口的定义格式与类的定义格式基本相同&#xff0c;将class关键字替换为interface关键字&#xff1a;public interface IShape {}2.类与接口之间使用implements关键字来实现接口&a…

常用类学习

文章目录字符串相关的类String的特性String对象的创建字符串相关的类String类与其他结构之间的转换StringBuffer,StringBuilderStringBuffer类的常用方法JDK8之前日期时间APIjava.lang.System类java.util.Date类java.text.SimpleDateFormat类java.util.Calendar类JDK8中新日期时…

【Python库包】Gurobi-Optimize (求解 MIP) 安装

目录Step1&#xff1a;注册账号Step2&#xff1a;获取Licence另&#xff1a;完整安装 Gurobi软件参考本博客简介Gurobi-Optimizer的安装&#xff08;Python 环境&#xff09;。 Step1&#xff1a;注册账号 官网-Gurobi-Optimizer ⚠️注意&#xff1a; Gurobi 是商业软件&…

【渗透测试】NmapScanHelper 扫描辅助工具

目录NmapScanHelper 扫描辅助工具一、功能特性二、文件说明三、使用方法1. 安装依赖macOSUbuntu/DebianCentOS/RHEL2. 配置网段3. 运行扫描基本用法常用端口扫描示例扫描模式特殊环境模式选择性扫描自定义文件4. 查看结果四、扫描模式说明标准模式特殊环境模式五、支持的 Nmap …

Python爬虫入门到实战(1)-requests库

一.网络爬虫库网络爬虫通俗来讲就是使用代码将HTML网页的内容下载到本地的过程。爬取网页主要是为了获取网之间需要中的关键信息&#xff0c;例如网页中的数据、图片、视频等。urllib库:是Python自带的标准库&#xff0c;无须下载、安装即可直接使用。urllib库中包含大量的爬虫…

深入理解设计模式之代理模式:原理、实现与应用

在软件开发中&#xff0c;我们经常需要控制对某些对象的访问——可能是为了延迟加载、添加额外功能或保护敏感资源。这正是代理模式大显身手的地方。作为结构型设计模式的重要成员&#xff0c;代理模式在众多知名框架和系统中扮演着关键角色。本文将全面剖析代理模式的方方面面…

VSCode - VSCode 快速跳转标签页

VSCode 快速跳转标签页 1、标签页列表快速跳转 通过快捷键 Ctrl Tab 即可快速跳转标签页 # 操作方式先按住 Ctrl 键&#xff0c;再按 Tab 键&#xff0c;此时&#xff0c;即可打开标签页列表&#xff08;保持 Ctrl 键一直按住&#xff09;然后&#xff0c;再按 Tab 键&#xf…