list【1】介绍与使用(超详解哦)

news2024/11/26 18:44:19

list的介绍与使用

  • 引言
  • list介绍
  • 接口使用
    • 默认成员函数
    • 迭代器
    • 容量
    • 元素访问
    • 数据修改
  • list的算法接口
  • 总结

引言

继vector之后,我们继续来介绍STL容器:list
对于容器的使用其实有着类似的模式,参考之前vector的使用可以让我们更快的上手:
戳我看vector介绍与使用详解哦

list介绍

在之前C语言部分我们就认识了链表,STL中的list是一个双向链表

相对于vector的底层空间是连续的,list的底层空间是通过指针链接的链状的不连续的空间
这样的结构相较连续空间扩容更加方便:不需要重开空间移动数据,只需要在开辟一个新的结点后,将其与前面的结点链接起来即可。其在任意位置插入删除都不需要挪动数据,效率较高:只需要释放或增加对应结点的数据,然后将剩下的结点链接起来即可;
相较于vector,list不能实现高效的任意访问其中的元素,要随机访问元素只能从头或尾遍历访问,效率较低。所以list中也就直接没有实现operator[]

所以,list适用于需要经常在任意位置插入删除大量数据,且不需要经常访问任意位置元素的数据的存储
list是一个类模板,可以支持存储任意类型:
在这里插入图片描述

接口使用

与vector类似,list也有默认成员函数、迭代器、容量、元素访问、数据修改等接口(使用库list时需要包含头文件#include<list>

默认成员函数

构造
在这里插入图片描述
list的构造函数重载了4个版本,支持无参构造、n个指定元素构造、迭代器区间构造以及拷贝构造。迭代器区间构造是一个函数模板,即可以使用任一InputIterator迭代器区间来构造list。

使用时与vector类似,由于list是一个类模板,所以在使用list来实例化对象是,就需要显式指定模板参数,如list<int>

#include<iostream>
#include<list>
#include<vector>
using namespace std;

int main()
{
	list<int> l1; //无参初始化
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int> l2(10, 6);    //使用10个6初始化l2
	for (auto e : l2)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int> v1(10, 5);  //使用10个5初始化v1
	list<int> l3(v1.begin(), v1.end());  //使用迭代器区间初始化
	for (auto e : l3)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int> l4(l3); //拷贝构造
	for (auto e : l4)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

析构
在这里插入图片描述
析构函数会在list对象生命周期结束时由编译器自己调用,以释放其内部资源。

赋值重载
在这里插入图片描述
l2赋值给l1

int main()
{
	list<int> l1;
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int> l2(10, 6);
	for (auto e : l2)
	{
		cout << e << " ";
	}
	cout << endl;

	l1 = l2;  //将l2赋值给l1
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

迭代器

在这里插入图片描述
vector的迭代器的底层就是原生指针,与vector不同,list的迭代器是指针的封装(在list实现时会详细介绍),但是在使用list迭代器时是与vector几乎一致的。
但是需要注意的是,list的迭代器由于不是原生指针,在+-数字时的成本太高,所以就不支持迭代器+-,只允许迭代器进行++--的双向移动,即为bidirectional iterator

begin返回首元素位置的迭代器,end返回尾元素下一个位置的迭代器、rbegin返回尾元素的反向迭代器、rend返回首元素前一个位置的反向迭代器。后面的cbegincendcrbegincrend都是返回其对应的const迭代器,但是前面的函数都有重载const版本:

int main()
{
	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);
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << *l1.begin() << endl;
	cout << *(--l1.end()) << endl;
	cout << *l1.rbegin() << endl;
	cout << *(--l1.rend()) << endl;

	return 0;
}

在这里插入图片描述

容量

在这里插入图片描述
对于list,没有容量的概念,也就不需要有扩容的操作。
所以在容量部分,list只提供了sizeempty,用于返回list中元素个数与判断list是否为空

int main()
{
	vector<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);
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << "size:" << l1.size() << " ";
	cout << "is empty:" << l1.empty() << " ";

	return 0;
}

在这里插入图片描述

元素访问

在这里插入图片描述
list不是连续的空间,想要通过下标访问任意位置的元素时成本较高,所以list没有重载operator[],而只能通过迭代器访问元素;
同时,list提供了frontback接口来实现对首尾元素的访问

int main()
{
	vector<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);
	for (auto e : l1)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << l1.front() << endl;
	cout << l1.back() << endl;

	return 0;
}

在这里插入图片描述

数据修改

在这里插入图片描述
与vector类似

push_frontpush_back用于在头、尾插入一个元素;
pop_frontpop_back用于在头、尾删除一个元素;

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

	l.pop_back();
	l.pop_front();
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

在这里插入图片描述

在这里插入图片描述
insert用于在pos位置(迭代器位置)插入一些数据,包括单个元素、多个指定元素以及一个迭代器区间中的元素:

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

	l.insert(l.begin(), 10);  //相当于头插一个10
	l.insert(l.begin(), 3, 20);  //相当于头插3个20
	list<int> l2(3, 30);  //使用3个30构造l2
	l.insert(l.end(), l2.begin(), l2.end()); //相当于尾插一个l2
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

在这里插入图片描述
erase用于删除pos位置的一个元素或一个迭代器区间中的元素

int main()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	l.push_back(5);
	l.push_back(6);

	l.erase(++l.begin(), --l.end());
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;

	l.erase(l.begin());  //相当于头删
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

在这里插入图片描述
resize用于修改list中的容量:
n小于list的元素个数时,就删除至n个元素;
n大于list的元素个数时,就用指定元素value补足:

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

	l.resize(3);  //删至3个元素
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;

	l.resize(10, 6); //补到10个元素,不足的用6补
	for (auto e : l)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

swap用于交换两个list中的数据
clear用于清理list中的数据,这里就不再演示了。

list的算法接口

在这里插入图片描述
同时,list还提供了一些算法接口,如reversesort等。

  1. 对于reverse算法库中的接口,是通过循环左右交换的方式来实现的:
    在这里插入图片描述
    对于list这样,通过逻辑连续的线性结构,我们可以使用更为简单的改变链接顺序的方法来实现反转,list的算法中就是这样实现的(戳我看反转链表OJ 思路与该算法类似)

  2. 对于算法库中sort的接口,使用的是快排的方式来排序的,快排算法是需要三数取中来优化的,即他需要能够+-RandomAccessIterator迭代器作为参数:
    在这里插入图片描述
    而list的迭代器却不支持+-的操作,所以不能使用算法库中的sort函数,所以list提供了这个接口。
    但是list中的sort函数效率远没有快排的效率高,所以在进行大量list数据的排序时,可以将其数据转移到vector中排序后再转移回来;也可以干脆不适用list来存储需要大量排序的数据

总结

到此,关于list的简介与接口使用就介绍完了
接下来会进行模拟实现,欢迎持续关注哦

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦

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

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

相关文章

Focal Loss-解决样本标签分布不平衡问题

文章目录 背景交叉熵损失函数平衡交叉熵函数 Focal Loss损失函数Focal Loss vs Balanced Cross EntropyWhy does Focal Loss work? 针对VidHOI数据集Reference 背景 Focal Loss由何凯明提出&#xff0c;最初用于图像领域解决数据不平衡造成的模型性能问题。 交叉熵损失函数 …

嵌入式底层驱动需要知道的基本知识

先说结论&#xff0c;能&#xff0c;肯定能&#xff0c;必须能&#xff01; 但是&#xff0c;问题重点在于坚持&#xff0c;程序员这一行 &#xff0c;下班回家一般都要10点了&#xff0c;再刷两个小时枯燥的学习视频&#xff0c;我想大多数人是坚持不下来的。 但是&#xff…

ABB D674A906U01流量计变送器模块

流量测量&#xff1a; 该模块用于准确测量液体或气体的流量&#xff0c;通常以标准单位&#xff08;如立方米每小时或加仑每分钟&#xff09;表示。 传感器技术&#xff1a; 它通常使用各种传感器技术&#xff08;例如涡轮、电磁、超声波等&#xff09;来检测流体的流动并进行…

冠达管理:股票停牌后会大涨吗?

股票停牌是指证券买卖所为了保护市场秩序、保护出资者利益等原因暂时中止某些股票的买卖。但是&#xff0c;股票停牌前的股价与停牌后的股价会有什么不同呢&#xff1f;股票停牌后是否会大涨呢&#xff1f;在本文中&#xff0c;咱们将从多个视点进行剖析&#xff0c;以帮助人们…

合宙Air724UG LuatOS-Air LVGL API控件--按钮 (Button)

按钮 (Button) 按钮控件&#xff0c;这个就不用多说了&#xff0c;界面的基础控件之一。 示例代码 – 按键回调函数 event_handler function(obj, event) if event lvgl.EVENT_CLICKED then print(“Clicked\n”) elseif event lvgl.EVENT_VALUE_CHANGED then print(“To…

java.lang.IllegalStateException: Unable to find

java.lang.IllegalStateException: Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or SpringBootTest(classes…) with your test 错误场景&#xff1a;在使用mybatisplus做测试时&#xff0c;出现此错误 解决方案&#xff1a;SpringBoot…

【MCU】SD NAND芯片之国产新选择

文章目录 前言传统SD卡和可贴片SD卡传统SD卡可贴片SD卡 实际使用总结 前言 随着目前时代的快速发展&#xff0c;即使是使用MCU的项目上也经常有大数据存储的需求。可以看到经常有小伙伴这样提问&#xff1a; 大家好&#xff0c;请问有没有SD卡芯片&#xff0c;可以直接焊接到P…

python可视化matplotlib——绘制正弦和余弦

这是一个使用matplotlib库绘制正弦和余弦函数曲线的代码示例。代码中导入了需要的库&#xff0c;并设置了x轴和y轴的标签字体为华文楷体。然后&#xff0c;使用numpy生成一组x轴上的值t&#xff0c;并使用正弦函数生成对应的y轴值s&#xff0c;再使用余弦函数生成对应的y轴值z。…

使用Tampermonkey(篡改猴)向页面注入js脚本

一、Tampermonkey 简单介绍 Tampermonkey是一款浏览器插件&#xff0c;适用于Chrome、Microsoft Edge、Safari、Opera Next 和 Firefox。他允许我们自定义javascript给指定网页添加功能&#xff0c;或修改现有功能。也可以用来辅助调试&#xff0c;或去除网页广告等。 官网地…

Vulkan LoaderLayer

目录 一、Loader The Loader 二、Layer 调度链Dispatch Chains JSON 一、Loader Vulkan是一个层架构&#xff0c;由Vulkan ApplicationLoaderLayerICDs(Installable Client Drivers)组成。 Vulkan 是一个显式 API&#xff0c;可以直接控制 GPU 的实际工作方式。因此&#x…

get请求报错400 非法参数

get请求报错400 非法参数 背景&#xff1a;get请求数据&#xff0c;SpringBoot提供接口&#xff0c;返回400&#xff0c;报错非法参数此种情况排除接口本身错误之外&#xff0c;检查参数中有没有特殊字符 " < > [ \ ] ^ { | } 我这边就是因为其中一个参数中有中括…

数字货运保持深层角力,满帮业绩与投资价值双丰收

上半年&#xff0c;经济持续活跃&#xff0c;货运物流行业承担着帮助经济要素流通的职责&#xff0c;也成为最直接的受益者。 数字货运平台满帮8月23日发布的财报显示&#xff0c;2023年第二季度&#xff0c;其平台单量、用户量均取得显著增长&#xff0c;并带动平台业绩创下新…

【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能 1、数…

Android——基本控件(下)(十九)

1. 菜单&#xff1a;Menu 1.1 知识点 &#xff08;1&#xff09;掌握Android中菜单的使用&#xff1b; &#xff08;2&#xff09;掌握选项菜单&#xff08;OptionsMenu&#xff09;的使用&#xff1b; &#xff08;3&#xff09;掌握上下文菜单&#xff08;ContextMenu&am…

STM32F4_SD卡

目录 前言 1. SDIO协议简介 2. SDIO命令及响应 3. SD卡的操作模式及切换 4. STM32的SDIO接口 5. SDIO结构体 6. SDIO相关寄存器 7. 实验程序 7.1 main.c 7.2 SDIO_Card.c 7.3 SDIO_Card.h 前言 在之前的单片机学习过程中&#xff0c;我们已经了解到了单片机系统都需…

SQL server开启变更数据捕获(CDC)

一、CDC简介 变更数据捕获&#xff08;Change Data Capture &#xff0c;简称 CDC&#xff09;&#xff1a;记录 SQL Server 表的插入、更新和删除操作。开启cdc的源表在插入、更新和删除操作时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中&#xff0c;通过…

java子类继承父类方法、或者接口中方法的javadoc注释

说明 详情可以阅读&#xff1a; https://docs.oracle.com/en/java/javase/19/docs/specs/javadoc/doc-comment-spec.html#method-comment-inheritance 子类继承父类、或者子类实现接口&#xff0c;在子类中为了避免重复写注释&#xff0c;可以在子类方法注释的主要描述部分、或…

基于GitHooks实现项目自动实时部署

目录 基于GitHooks实现项目自动部署 基于SVNJenkins发布项目 基于GitHooks实现项目自动部署 以上创建的所有任务&#xff0c;构建工作是基于在开发人员提交完代码到远程仓库完成&#xff0c;通知运维后&#xff0c;需要手动执行构建任务&#xff0c;这样就有些不太方便。我们…

智能优化算法一元函数优化

目录 一、问题描述 二、解决方法 1.模拟退火 1.1 算法思路 1.2 求解代码 1.3 计算结果 2.粒子群算法 2.1 算法思路 2.2 求解代码 2.3 计算结果 3.遗传算法 3.1 算法思路 3.2 求解代码 3.3 计算结果 一、问题描述 本篇文章所做的是分别用模拟退火、粒子群算法…

MySQL 8.1安装

1. 下载地址 https://dev.mysql.com/downloads/mysql/8.0.html 我这里没有采用installer安装&#xff0c;因为installer安装依赖visual studio&#xff0c;所以&#xff0c;我下载的是zip文件。 最终下载的版本如下&#xff1a; 2. 添加环境变量 解压&#xff0c;添加环境…