list从0到1的突破

目录

前言

1.list的介绍

2.list的常见接口

2.1 构造函数( (constructor))  +接口说明    

2.2 list iterator 的使用

 2.3 list capacity

2.4 list element access

2.5 list modifiers

3.list的迭代器失效

附整套练习源码

结束语


前言

前面我们学习了vector,本节我们将对新的容器list进行拆分学习,并且有了string和vector的基础,list容器的方法学习起来就会轻松很多。

1.list的介绍

 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。

3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。

4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。

5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)

2.list的常见接口

2.1 构造函数( (constructor))  +接口说明    

list (size_type n, const value_type& val = value_type())     构造的list中包含n个值为val的元素

list()         拷贝空的list

list (const list& x)     拷贝构造函数

list (InputIterator first, InputIterator last)      用[first, last)区间中的元素构造list

void test1() {list<int>l1;list<int>l2(5, 10);list<int>l3(l2.begin(), l2.end());//迭代器构造list<int>l4(l2);//拷贝构造//以数组区间迭代器构造listfloat arr[] = { 5.20,13.14,9.99,8.88 };list<float>l5(arr, arr + sizeof(arr) / sizeof(float));// 列表格式初始化C++11list<int> l6{ 1,2,3,4,5 };// 用迭代器方式打印l5中的元素list<float> ::iterator it = l5.begin();while (it != l5.end()) {cout << *it << " ";it++;}cout << endl;// C++11范围for的方式遍历for (auto e : l6) {cout << e << " ";}
}

注意:遍历链表只能用迭代器和范围for

2.2 list iterator 的使用

void TestList2()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin();   // C++98中语法auto it = l.begin();                     // C++11之后推荐写法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}

跟vector几乎是一样的

注意:

1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动 

 2.3 list capacity

2.4 list element access

 官方测试代码展示

list<int> mylist;mylist.push_back(10);while (mylist.back() != 0)
{mylist.push_back(mylist.back() - 1);
}cout << "mylist contains:";
for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;cout << '\n';

 

2.5 list modifiers

push_front    在list首元素前插入值为val的元素       pop_front    删除list中第一个元素 

push_back     在list尾部插入值为val的元素             pop_back删除list中最后一个元素 insert    在list position 位置中插入值为val的元素   erase删除list position位置的元素

swap交换两个list中的元素                                        clear清空list中的有效元素 

void print_list(const list<int>& ml) {// 注意这里调用的是list的 begin() const,返回list的const_iterator对象list<int>::const_iterator it = ml.begin();while (it != ml.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList3() {list<int>mylist{ 1,2,3,4,5 };mylist.push_back(6);mylist.push_front(0);print_list(mylist);mylist.pop_back();mylist.pop_front();print_list(mylist);
}
void TestList4()
{int array1[] = { 1, 2, 3 };list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));// 获取链表中第二个节点//auto pos = ++L.begin();list<int>::iterator pos = ++L.begin();cout << *pos << endl;// 在pos前插入值为4的元素L.insert(pos, 4);print_list(L);// 在pos前插入5个值为5的元素L.insert(pos, 5, 5);print_list(L);// 在pos前插入[v.begin(), v.end)区间中的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());print_list(L);// 删除pos位置上的元素L.erase(pos);print_list(L);// 删除list中[begin, end)区间中的元素,即删除list中的所有元素L.erase(L.begin(), L.end());print_list(L);
}

 这里我们设置了一个打印链表值的函数,方便打印链表,只是打印整数,想打印其他值可以参考vector建立一个模版打印函数,让编译器自己推测打印数据的类型。

template <class Container>
void print(const Container& v) {auto it = v.begin();while (it != v.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList5()
{// 用数组来构造listint array1[] = { 1, 2, 3 ,4 ,5};list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));print_list(l1);list<int>l2{ 6,7,8,9,10 };// 交换l1和l2中的元素l1.swap(l2);print_list(l1);print_list(l2);// 将l2中的元素清空l2.clear();cout << l2.size() << endl;
}

3.list的迭代器失效

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

void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));auto it = l1.begin();while (it != l1.end()) {l1.erase(it);it++;}
}

修改后:

void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {//等价于l1.erase(it++);it = l1.erase(it);}print(l1);
}

 变式删除偶数:

void TestList1() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1(arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {if(*it%2==0)it = l1.erase(it);elseit++;}print(l1);
}

附整套练习源码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
#include <vector>
using namespace std;
void test1() {list<int>l1;list<int>l2(5, 10);list<int>l3(l2.begin(), l2.end());//迭代器构造list<int>l4(l2);//拷贝构造//以数组区间迭代器构造listfloat arr[] = { 5.20,13.14,9.99,8.88 };list<float>l5(arr, arr + sizeof(arr) / sizeof(float));// 列表格式初始化C++11list<int> l6{ 1,2,3,4,5 };// 用迭代器方式打印l5中的元素list<float> ::iterator it = l5.begin();while (it != l5.end()) {cout << *it << " ";it++;}cout << endl;// C++11范围for的方式遍历for (auto e : l6) {cout << e << " ";}cout << endl;cout << l5.size() << endl;
}
void TestList2()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin();   // C++98中语法auto it = l.begin();                     // C++11之后推荐写法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}
void test3() {list<int> mylist;mylist.push_back(10);while (mylist.back() != 0){mylist.push_back(mylist.back() - 1);}cout << "mylist contains:";for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;cout << '\n';}
template <class Container>
void print(const Container& v) {auto it = v.begin();while (it != v.end()) {cout << *it << " ";it++;}cout << endl;
}
void print_list(const list<int>& ml) {// 注意这里调用的是list的 begin() const,返回list的const_iterator对象list<int>::const_iterator it = ml.begin();while (it != ml.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList3() {list<int>mylist{ 1,2,3,4,5 };mylist.push_back(6);mylist.push_front(0);print_list(mylist);mylist.pop_back();mylist.pop_front();print_list(mylist);
}
void TestList4()
{int array1[] = { 1, 2, 3 };list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));// 获取链表中第二个节点//auto pos = ++L.begin();list<int>::iterator pos = ++L.begin();cout << *pos << endl;// 在pos前插入值为4的元素L.insert(pos, 4);print_list(L);// 在pos前插入5个值为5的元素L.insert(pos, 5, 5);print_list(L);// 在pos前插入[v.begin(), v.end)区间中的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());print_list(L);// 删除pos位置上的元素L.erase(pos);print_list(L);// 删除list中[begin, end)区间中的元素,即删除list中的所有元素L.erase(L.begin(), L.end());print_list(L);
}
void TestList5()
{// 用数组来构造listint array1[] = { 1, 2, 3 ,4 ,5};list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));//print_list(l1);print(l1);list<int>l2{ 6,7,8,9,10 };// 交换l1和l2中的元素l1.swap(l2);//print_list(l1);//print_list(l2);print(l1);print(l2);// 将l2中的元素清空l2.clear();cout << l2.size() << endl;
}
void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {//等价于l1.erase(it++);it = l1.erase(it);}print(l1);
}
void TestList1() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1(arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {if(*it%2==0)it = l1.erase(it);elseit++;}print(l1);
}
int main() {//test3();TestList1();return 0;
}

结束语

本节内容就到此结束啦,相信大家对list有了进一步的了解,下节我们将一步一步实现自己的list!

最后感谢各位友友的支持,给小编点个赞吧!!! 

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

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

相关文章

FastAdmin CMS 操作手册

FastAdmin CMS 操作手册 概述&#xff1a; 安装&#xff1a; 配置&#xff1a; 模板&#xff1a; 模板目录&#xff1a; 标签&#xff1a; 全局&#xff1a; 文章&#xff1a; 专题&#xff1a; 栏目&#xff1a; 公共参数&#xff1a; 单页&#xff1a; 特殊标签&#xff1a;…

138_Java基础_常用类搭建教程java部署mysql5.5

安装&#xff1a; yum -y install build-essential QQ1594457675 安装&#xff1a;更多依赖包 yum -y install gcc automake autoconf libtool make 安装&#xff1a;数据库 这里需要注意数据库密码记得修改 数据库账号QQ 数据库密码1594457675 yum -y install gcc …

Linux 文件 IO 管理(第一讲)

Linux 文件 IO 管理&#xff08;第一讲&#xff09; 回顾 C 语言文件操作&#xff0c;提炼理解新创建的文件为什么被放在可执行文件的同级目录下&#xff1f;上述 log.txt 何时被创建&#xff1f;又是谁在打开它&#xff1f;那文件没有被打开的时候在哪里&#xff1f;一个进程可…

电脑的固态硬盘

常见种类 1.SATA接口&#xff1a;一般由一个铁盒子&#xff0c;里面装着控制芯片&#xff0c;以及内存颗粒组成的SSD硬盘。 比机械硬盘读写速度快&#xff0c;比M.2读写速度慢。目前常用的是3.0 2.M.2 PCI-E接口&#xff1a;无机械零件设计&#xff0c;相当于没有噪音。速度比…

Chrome谷歌浏览器登录账号next无反应

文章目录 问题描述 我们的Chrome浏览器在更新之后&#xff0c;会出现登录谷歌账号的时候&#xff0c;当你输入你的谷歌邮箱之后&#xff0c;点击 n e x t next next,也就是下一步的时候&#xff0c;页面没有反应&#xff0c;也就是没有跳转到输入密码的页面。 分析 根据logs里…

借助大模型将文档转换为视频

利用传统手段将文档内容转换为视频&#xff0c;比如根据文档内容录制一个视频&#xff0c;不仅需要投入大量的时间和精力&#xff0c;而且往往需要具备专业的视频编辑技能。使用大模型技术可以更加有效且智能化地解决上述问题。本实践方案旨在依托大语言模型&#xff08;Large …

[数据集][目标检测]疟疾恶性疟原虫物种目标检测数据集VOC+YOLO格式948张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;948 标注数量(xml文件个数)&#xff1a;948 标注数量(txt文件个数)&#xff1a;948 标注类别…

【C++】——继承详解

目录 1、继承的概念与意义 2、继承的使用 2.1继承的定义及语法 2.2基类与派生类间的转换 2.3继承中的作用域 2.4派生类的默认成员函数 <1>构造函数 <2>拷贝构造函数 <3>赋值重载函数 <4析构函数 <5>总结 3、继承与友元 4、继承与静态变…

蓝桥杯—STM32G431RBT6按键的多方式使用(包含软件消抖方法精讲)从原理层面到实际应用(一)

新建工程教程见http://t.csdnimg.cn/JySLg 点亮LED教程见http://t.csdnimg.cn/Urlj5 末尾含所有代码 目录 按键原理图 一、按键使用需要解决的问题 1.抖动 1.什么是抖动 2.抖动类型 3.如何去消除抖动 FIRST.延时函数消抖&#xff08;缺点&#xff1a;浪费CPU资源&#xff…

Python(TensorFlow和PyTorch)及C++注意力网络导图

&#x1f3af;要点 谱图神经网络计算注意力分数对比图神经网络、卷积网络和图注意力网络药物靶标建模学习和预测相互作用腹侧和背侧皮质下结构手写字体字符序列文本识别组织病理学图像分析长短期记忆财务模式预测相关性生物医学图像特征学习和迭代纠正 Python注意力机制 对…

深度学习Day-33:Semi-Supervised GAN理论与实战

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 一、 基础配置 语言环境&#xff1a;Python3.8编译器选择&#xff1a;Pycharm深度学习环境&#xff1a; torch1.12.1c…

3 种自然语言处理(NLP)技术:RNN、Transformers、BERT

自然语言处理 (NLP) 是人工智能的一个领域&#xff0c;旨在使机器能够理解文本数据。NLP 研究由来已久&#xff0c;但直到最近&#xff0c;随着大数据和更高计算处理能力的引入&#xff0c;它才变得更加突出。 随着 NLP 领域的规模越来越大&#xff0c;许多研究人员都试图提高…

【 html+css 绚丽Loading 】000051 方寸轮回矩

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…

蓝桥杯-基于STM32G432RBT6的LCD进阶(LCD界面切换以及高亮显示界面)

目录 一、页面切换内容详解 1.逻辑解释 2.代码详解 code.c&#xff08;内含详细讲解&#xff09; code.h main.c 3.效果图片展示 ​编辑 二、页面选项高亮内容详解 1.逻辑解释 2.读入数据 FIRST.第一种高亮类型 code.c&#xff08;内含代码详解&#xff09; code.…

[000-01-008].第05节:OpenFeign特性-重试机制

我的后端学习大纲 SpringCloud学习大纲 1.1.重试机制的默认值&#xff1a; 1.重试机制默认是关闭的&#xff0c;给了默认值 1.2.测试重试机制的默认值&#xff1a; 1.3.开启Retryer功能&#xff1a; 1.修改配置文件YML的配置&#xff1a; 2.新增配置类&#xff1a; packa…

大模型时代:普通人如何获利

随着人工智能技术的飞速发展&#xff0c;我们正步入一个以大模型为驱动力的新时代。这些大型语言模型&#xff0c;如GPT-3和BERT&#xff0c;已经在各个领域展现出惊人的能力&#xff0c;包括文本生成、翻译、问答等。这些技术的进步不仅改变了我们的生活&#xff0c;也为普通人…

【ACM出版】第三届人工智能与智能信息处理国际学术会议(AIIIP 2024,10月25-27)

第三届人工智能与智能信息处理国际学术会议&#xff08;AIIIP 2024&#xff09; 2024 3rd International Conference on Artificial Intelligence and Intelligent Information Processing 中国-天津 | 2024年10月25-27日 | 会议官网&#xff1a;www.aiiip.net 官方信息 会议…

Redis常用操作及springboot整合redis

1. Redis和Mysql的区别 数据模型&#xff1a;二者都是数据库,但是不同的是mysql是进行存储到磁盘当中,而Redis是进行存储到内存中. 数据模型 : mysql的存储的形式是二维表而Redis是通过key-value键值对的形式进行存储数据. 实际的应用的场景: Redis适合于需要快速读写的场景&…

[Linux]:进程间通信(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. system V通信 前面我们所探究的通信方式都是基于管道文件的&#xff0c;而…

深入解析代理模式:静态代理、JDK 动态代理和 CGLIB 的全方位对比!

代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它提供了对象的替身&#xff0c;即代理对象来控制对实际对象的访问。通过代理对象&#xff0c;可以在不修改目标对象的情况下&#xff0c;扩展或控制其功能。例如&#xff0c;代理模式可以用于延…