【C++】第九节:list

1、list的介绍及使用

1.1 list的介绍

list - C++ 参考

1.2 list的使用

1.2.1 list的构造

void TestList1()
{list<int> l1; // 构造空的l1list<int> l2(4, 100); // l2中包含4个值为100的元素list<int> l3(l2.begin(), l2.end()); // 用l2的[begin(),end())构造l3list<int> l4(l3); // 用l3拷贝构造l4// 以数组为迭代器区间构造l5int arr[] = { 16,2,77,29 };list<int> l5(arr, arr + sizeof(arr) / sizeof(int));// 列表格式初始化C++11list<int> l6{ 1,2,3,4,5 };list<int>::iterator it = l5.begin();while (it != l5.end()){cout << *it << " ";++it;}cout << endl;for (auto& e : l6){cout << e << " ";}cout << endl;
}

1.2.2 list iterator的使用

// 注意:遍历链表只能用迭代器和范围for
void TestList2()
{int arr[] = { 1,2,3,4,5,6,7,8,9,0 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));// 使用正向迭代器遍历list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器遍历list<int>::reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;// 使用for循环遍历// 注意这里调用的是list的begin() const,返回list的const_iterator对象for (list<int>::const_iterator cit = l.begin(); cit != l.end(); ++cit){cout << *cit << " ";//*cit = 10; // 编译不通过}cout << endl;
}

1.2.3 list capacity

1.2.4 list element access

1.2.5 list modifiers

void TestList3()
{int arr[] = { 1,2,3 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));// 在l的尾部插入4,头部插入0l.push_back(4);l.push_front(0);for (auto& e : l){cout << e << " ";}cout << endl;// 获取链表第二个节点auto pos = ++l.begin();// 在pos位置之前插入7l.insert(pos, 7);// 用迭代器区间插入vector<int> v{ 4,5,6 };l.insert(pos, v.begin(), v.end());for (auto& e : l){cout << e << " ";}cout << endl;// 删除pos位置上的元素l.erase(pos);for (auto& e : l){cout << e << " ";}cout << endl;
}
void TestList4()
{int arr[] = { 1,2,3 };list<int> l1(arr, arr + sizeof(arr) / sizeof(arr[0]));// 交换l1和l2中的元素list<int> l2;l1.swap(l2);for (auto& e : l1){cout << e << " ";}cout << endl;for (auto& e : l2){cout << e << " ";}cout << endl;// 清空l2中的元素l2.clear();cout << l2.size() << endl;
}

1.2.6 list operations

void TestList5()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);for (auto e : lt){cout << e << " ";}cout << endl;lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;//sort(lt.begin(), lt.end()); // 报错,因为list底层是双向迭代器,而sort需要随机迭代器// 升序 < less//lt.sort(); // 降序 > greater//greater<int> gt;//lt.sort(gt);lt.sort(greater<int>()); // 匿名对象for (auto e : lt){cout << e << " ";}cout << endl;
}

void TestList6();
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(3);lt.push_back(3);lt.push_back(3);lt.push_back(5);lt.push_back(5);lt.push_back(3);for (auto e : lt){cout << e << " ";}cout << endl;lt.sort(); // 先排序lt.unique();// 再去重for (auto e : lt){cout << e << " ";}cout << endl;lt.remove(3);for (auto e : lt){cout << e << " ";}cout << endl;
}

1.2.7 list迭代器失效

此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点无效,即该节点被删除了。因为 list 的底层结构为带头结点的双向循环链表,因此在 list 中进行插入时是不会导致迭代器失效的,只有删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

void TestListIterator1()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值l.erase(it);++it;}
}// 改正
void TestListIterator()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));auto it = l.begin();while (it != l.end()){l.erase(it++); // it++作为参数传递给l.erase()}
}

2、list的模拟实现

2.1 模拟实现list

namespace yf
{// list的节点类(模板类)template<class T>struct list_node{T _data;list_node<T>* _next;list_node<T>* _prev;// T不一定是int,所以不能直接给0,要用匿名对象list_node(const T& x = T()) :_data(x), _next(nullptr), _prev(nullptr){}};template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> self;Node* _node;__list_iterator(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& s){return _node != s._node; // !=运算符是内置的指针比较运算符}bool operator==(const self& s){return _node == s._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;const_iterator begin() const{// 这里跳到迭代器的构造函数创建了一个新的const_iterator对象,// 使其指向_head->_next节点return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}iterator begin(){//return iterator(_head->_next);return _head->_next; // list_node<T>*会被隐式类型转换为iteator对象}iterator end(){//return iterator(_head);return _head;}// 空初始化void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}// 无参构造函数list(){empty_init();}// lt2(lt1)list(const list<T>& lt){// 先构造一个空的lt2empty_init();for (auto e : lt){push_back(e);}}void swap(list<int>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}// lt3 = lt2list<int>& operator=(list<int> lt){swap(lt);return *this;}~list(){clear();delete _head;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}void push_back(const T& x){insert(end(), x);}void pop_front(){erase(begin());}void pop_back(){erase(--end());}// 在pos位置之前插入,返回新插入的位置iterator 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;++_size;return iterator(newnode);}// 删除pos节点,返回pos节点的下一个节点的迭代器iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;delete cur;prev->_next = next;next->_prev = prev;--_size;return iterator(next);}size_t size(){return _size;}private:Node* _head;size_t _size;};void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);// 封装list<int>::iterator it = lt.begin();while (it != lt.end()){*it += 20;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list2(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int> lt1(lt);for (auto e : lt1){cout << e << " ";}cout << endl;list<int> lt2;lt2.push_back(10);lt2.push_back(20);lt2.push_back(30);lt2.push_back(40);lt2.push_back(50);lt1 = lt2;for (auto e : lt1){cout << e << " ";}cout << endl;}struct AA{AA(int a1 = 0, int a2 = 0):_a1(a1), _a2(a2){}int _a1;int _a2;};void test_list3(){list<AA> lt;lt.push_back(AA(1, 1));lt.push_back(AA(2, 2));lt.push_back(AA(3, 3));list<AA>::iterator it = lt.begin();while (it != lt.end()){cout << it->_a1 << " " << it->_a2 << endl;cout << it.operator->()->_a1 << " " << it.operator->()->_a2 << endl;++it;}cout << endl;}//template<typename T>//void print_list(const list<T>& lt)//{//	// list<T>是未实例化的类模板,编译器不能去他里面找//	// 编译器无法判断list<T>::const_iterator是内嵌类型,还是静态成员变量//	// 前面加一个typename就是告诉编译器,这是一个类型,等list<T>实例化//	// 再去类里面找//	typename list<T>::const_iterator it = lt.begin();//	while (it != lt.end())//	{//		cout << *it << " ";//		++it;//	}//	cout << endl;//}template<typename Container>void print_container(const Container& con){typename Container::const_iterator it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;}void test_list4(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);print_container(lt);vector<string> v;v.push_back("11111111111");v.push_back("11111111111");v.push_back("11111111111");v.push_back("11111111111");print_container(v);}
}

3、list与vector的对比

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

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

相关文章

Idea中创建和联系MySQL等数据库

备注&#xff1a;电脑中要已下好自己需要的MySQL数据库软件 MySQL社区版下载链接&#xff1a; https://dev.mysql.com/downloads/installer/ 优点&#xff1a; 1.相比与在命令行中管理数据库&#xff0c;idea提供了图形化管理&#xff0c;简单明了&#xff1b; 2.便于与后端…

Linux_shell脚本if语句详细教程

前言 在 Linux Shell 脚本中&#xff0c;if 语句用于基于条件执行命令或代码块。它的基本语法结构如下&#xff1a; if 条件; then# 如果条件为真时执行的代码 elif 另一个条件; then# 如果另一个条件为真时执行的代码 else# 如果所有条件都不成立时执行的代码 fi一、if 语句…

Python自学之Colormaps指南

目录 1.色彩映射表&#xff08;Colormaps&#xff09;是什么&#xff1f; 2.Matplotlib中的色彩映射表类型 2.1同色渐变&#xff08;Sequential Colormaps&#xff09; 2.2双色渐变&#xff08;Divergence Colormaps&#xff09; 2.3定性色彩&#xff08;Qualitative Col…

利用redis的key失效监听器KeyExpirationEventMessageListener作任务定时提醒功能

某需求&#xff1a; 要求在任务截止日期的前3天时&#xff0c;系统自动给用户发一条消息提醒。 用定时任务的话感觉很不舒服。间隔时间不好弄。不能精准卡到那个点。 由于系统简单&#xff0c;没有使用消息列队&#xff0c;也不能使用延时队列来做。 用Timer的话开销还挺大的&a…

从视频帧生成点云数据、使用PointNet++模型提取特征,并将特征保存下来的完整实现。

文件地址 https://github.com/yanx27/Pointnet_Pointnet2_pytorch?spm5176.28103460.0.0.21a95d27ollfze Pointnet_Pointnet2_pytorch\log\classification\pointnet2_ssg_wo_normals文件夹改名为Pointnet_Pointnet2_pytorch\log\classification\pointnet2_cls_ssg "E:…

高效工具推荐:基于WebGPU的Whisper Web结合内网穿透远程使用指南

文章目录 前言1.本地部署Whisper Web1.1 安装git1.2 安装Node.js1.3 运行项目 2. Whisper Web使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 公网访问测试6. 配置固定公网地址 前言 OpenAI开源的 Whisper 语音转文本模型效果都说还不错&#xff0c;今天就给大家推荐 GitHub…

大数据学习16之Spark-Core

1. 概述 1.1.简介 Apache Spark 是专门为大规模数据处理而设计的快速通用的计算引擎。 一种类似 Hadoop MapReduce 的通用并行计算框架&#xff0c;它拥有MapReduce的优点&#xff0c;不同于MR的是Job中间结果可以缓存在内存中&#xff0c;从而不需要读取HDFS&#xff0c;减少…

Go语言跨平台桌面应用开发新纪元:LCL、CEF与Webview全解析

开篇寄语 在Go语言的广阔生态中&#xff0c;桌面应用开发一直是一个备受关注的领域。今天&#xff0c;我将为大家介绍三款基于Go语言的跨平台桌面应用开发框架——LCL、CEF与Webview&#xff0c;它们分别拥有独特的魅力和广泛的应用场景。通过这三款框架&#xff0c;你将能够轻…

机器学习day5-随机森林和线性代数1最小二乘法

十 集成学习方法之随机森林 集成学习的基本思想就是将多个分类器组合&#xff0c;从而实现一个预测效果更好的集成分类器。大致可以分为&#xff1a;Bagging&#xff0c;Boosting 和 Stacking 三大类型。 &#xff08;1&#xff09;每次有放回地从训练集中取出 n 个训练样本&…

Excel使用-弹窗“此工作簿包含到一个或多个可能不安全的外部源的链接”的发生与处理

文章目录 前言一、探讨问题发生原因1.引入外部公式2.引入外部数据验证二、问题现象排查及解决1.排查公式2.排查数据验证3.特殊处理方式总结前言 作为一种常用的办公软件,Excel被大家所熟知。尽管使用了多年,有时候在使用Excel时候也会发生一些不太常见的现象,需要用心核查下…

跨越网络边界:IPv6与零信任架构的深度融合

2024年&#xff0c;工信部发布了《关于开展“网络去NAT”专项工作 进一步深化IPv6部署应用的通知》&#xff0c;加速了国内网络由IPv4向IPv6的转型步伐。未来&#xff0c;各行各业将逐步去NAT&#xff0c;逐步向IPv6迁移。在此过程中&#xff0c;网络安全解决方案和产品能力将面…

从大数据到大模型:现代应用的数据范式

作者介绍&#xff1a;沈炼&#xff0c;蚂蚁数据部数据库内核负责人。2014年入职蚂蚁&#xff0c;承担蚂蚁集团的数据库架构职责&#xff0c;先后负责了核心链路上OceanBase&#xff0c;OceanBase高可用体系建设、NoSQL数据库产品建设。沈炼对互联网金融、数据库内核、数据库高可…

华为eNSP:MSTP

一、什么是MSTP&#xff1f; 1、MSTP是IEEE 802.1S中定义的生成树协议&#xff0c;MSTP兼容STP和RSTP&#xff0c;既可以快速收敛&#xff0c;也提供了数据转发的多个冗余路径&#xff0c;在数据转发过程中实现VLAN数据的负载均衡。 2、MSTP可以将一个或多个VLAN映射到一个Inst…

MATLAB绘制克莱因瓶

MATLAB绘制克莱因瓶 clc;close all;clear all;warning off;% clear all rand(seed, 100); randn(seed, 100); format long g;% Parameters u_range linspace(0, 2*pi, 100); v_range linspace(0, pi, 50); [U, V] meshgrid(u_range, v_range);% Parametric equations for t…

2、 家庭网络发展现状

上一篇我们讲了了解家庭网络历史(https://blog.csdn.net/xld_hung/article/details/143639618?spm1001.2014.3001.5502),感兴趣的同学可以看对应的文章&#xff0c;本章我们主要讲家庭网络发展现状。 关于家庭网络发展现状&#xff0c;我们会从国内大户型和小户型的网络说起&…

Vue3 -- 项目配置之eslint【企业级项目配置保姆级教程1】

下面是项目级完整配置1➡eslint&#xff1a;【吐血分享&#xff0c;博主踩过的坑你跳过去&#xff01;&#xff01;跳不过去&#xff1f;太过分了给博主打钱】 浏览器自动打开项目&#xff1a; 你想释放双手吗&#xff1f;你想每天早上打开电脑运行完项目自动在浏览器打开吗&a…

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型&#xff08;E-R数据模型&#xff09;被开发来方便数据库的设计&#xff0c;它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…

LLM - 计算 多模态大语言模型 的参数量(Qwen2-VL、Llama-3.1) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143749468 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 影响 (…

基于Java Springboot成都旅游网

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

css 使用图片作为元素边框

先看原始图片 再看效果 边框的四个角灭有拉伸变形,但是图片的中部是拉伸的 代码 border-style: solid;/* 设置边框图像的来源 */border-image-source: url(/static/images/mmwz/index/bk_hd3x.png);/* 设置如何切割图像 */border-image-slice: 66;/* 设置边框的宽度 */border…