当前位置: 首页 > article >正文

C++——list的了解和使用

目录

引言

forward_list与list

标准库中的list

一、list的常用接口

1.list的迭代器

2.list的初始化

3.list的容量操作

4.list的访问操作

5.list的修改操作

6.list的其他操作

二、list与vector的对比

结束语


引言

本篇博客要介绍的是STL中的list。

求点赞收藏评论关注!!!十分感谢!!!

forward_list与list

首先我们先简单了解一下forward_list与list:

forward_list与list都是C++标准模板库(STL)中的容器,它们提供了不同的链表实现,适用于不同的场景。

forward_list

定义与结构:

1.forward_list是C++11引入的一种容器,它提供了一种单向链表的数据结构。

2.它只维护一个指向下一个节点的指针,因此内存使用相对高效。

特点:

1.只能在单向遍历,即只能从前往后遍历,不能反向遍历。

2.在已知位置的情况下,插入和删除操作非常高效,时间复杂度为O(1)。

3.不支持通过索引访问元素,只能使用迭代器进行访问。

适用场景:

1.适用于需要频繁进行前向遍历和插入、删除操作的场景。

2.当内存使用要求较高,且不需要双向遍历时,forward_list是更好的选择。

list

定义与结构:

1.list是C++标准库中基于带头双向循环链表实现的容器。

2.它支持双向迭代器,可以从前往后和从后往前遍历。

特点:

1.在任何位置进行插入和删除操作的时间复杂度都是近似O(1)。

2.支持双向遍历,迭代器使用更灵活。

3.与forward_list相比,内存占用稍多,因为每个节点需要维护两个指针(一个指向前一个节点,一个指向下一个节点)。

适用场景:

1.适用于需要双向遍历和更灵活操作的场景。

2.当需要在列表中间频繁插入或删除元素时,list是更好的选择。

具体内容可以看看这两篇文章:

数据结构——单链表

数据结构——双向链表

本文的重点是list。

标准库中的list

一、list的常用接口

list接口

1.list的迭代器

list的迭代器访问元素与我们之前学习的其他容器的迭代器访问一样。

int main()
{list<int> li = { 1, 2, 3, 4, 5 };list<int>::iterator it = li.begin();cout << "顺序遍历:";while (it != li.end()){cout << *it << " ";++it;}cout << endl;cout << "逆序遍历:";list<int>::reverse_iterator rit = li.rbegin();while (rit != li.rend()){cout << *rit << " ";++rit;}return 0;
}

由于list的迭代器是双向迭代器,支持++和--操作,因此可以在list中向前和向后遍历。

2.list的初始化

list的初始化与我们之前学习的其他容器的初始化一样,我们直接看个简单的使用示例:

int main()
{// 默认构造函数list<int> numbers1;cout << "默认构造: ";for (const auto& num : numbers1) {cout << num << " ";}cout << endl;// n个val构造list<int> numbers2(5, 5);cout << "n个val构造: ";for (const auto& num : numbers2) {cout << num << " ";}cout << endl;int arr[] = { 1, 2, 3, 4, 5 };// 通过vector的迭代器初始化list<int> numbers3(arr, arr + sizeof(arr) / sizeof(arr[0]));cout << "迭代器区间构造: ";for (const auto& num : numbers3) {cout << num << " ";}cout << endl;list<int> numbers4 = { 6, 7, 8, 9, 10 };// 拷贝构造list<int> numbers5(numbers4);cout << "拷贝构造: ";for (const auto& num : numbers5) {cout << num << " ";}cout << endl;numbers1 = numbers2;// 赋值重载cout << "赋值重载: ";for (const auto& num : numbers1) {cout << num << " ";}cout << endl;return 0;
}

输出结果为:

3.list的容量操作
函数名称功能
size返回列表中元素的数量
max_size返回列表可容纳的最大元素数量
empty检查列表是否为空,是则返回 true,否则返回 false
resize重新设置列表中元素的数量,超过原来数量则用默认值填充
clear清空列表中的所有元素

这些函数也是很容易理解的,我们还是直接看代码示例:

int main()
{list<int> li = { 1,2,3,4,5 };cout << "Size of list: " << li.size() << endl;cout << "Max size of list: " << li.max_size() << endl;if (li.empty()){cout << "empty" << endl;}else{cout << "not empty" << endl;}li.clear();if (li.empty()){cout << "empty" << endl;}else{cout << "not empty" << endl;}return 0;
}

输出结果为

与deque这一容器一样,list也没有reserve这一接口。

int main()
{list<int> li = { 1,2,3 };li.resize(5);for (auto& num : li){cout << num << " ";}cout << endl;li.resize(2);for (auto& num : li){cout << num << " ";}return 0;
}

输出结果为;

4.list的访问操作
函数名称功能
back返回列表最后一个元素
front返回列表第一个元素

由于list 是一个双向链表,不支持高效的随机访问。在链表中,访问某个元素需要从头节点开始顺序遍历,直到找到目标元素。因此,为 list 提供下标运算符或 at 方法并不合适。

访问操作的使用示例如下:

int main()
{list<int> li = { 1,2,3 };cout << li.front() << endl;cout << li.back() << endl;return 0;
}

输出结果为:

5.list的修改操作

常用的修改操作有如下几个:

函数名称功能
push_back在列表尾部添加元素
push_front在列表头部添加元素
pop_back删除列表最后一个元素
pop_front删除列表第一个元素
insert在指定位置插入元素
erase删除指定位置或区间的元素
swap交换两个列表
assign使用指定列表替换原列表

这些接口我们也是十分熟悉了,我们直接看代码示例:

尾删和尾插:

int main()
{list<int> li;li.push_back(1);li.push_back(2);li.push_back(3);li.push_back(4);for (auto& num : li) {cout << num << " ";}cout << endl;li.pop_back();for (auto& num : li){cout << num << " ";}cout << endl;return 0;
}

输出结果为:

头删和头插:

int main()
{list<int> li;li.push_front(1);li.push_front(2);li.push_front(3);li.push_front(4);for (auto& num : li){cout << num << " ";}cout << endl;li.pop_front();for (auto& num : li){cout << num << " ";}cout << endl;return 0;
}

输出结果为:

assign和swap:

int main()
{list<int> li1 = { 1,1,1,1,1 };li1.assign(3, 3);for (auto& num : li1){cout << num << " ";}cout << endl;list<int> li2 = { 2,2,2,2,2 };li1.swap(li2);for (auto& num : li1){cout << num << " ";}cout << endl;for (auto& num : li2){cout << num << " ";}return 0;
}

输出结果为:

insert:

int main()
{list<int> li = { 1,2,3,4,5 };list<int>::iterator it = li.begin();it = li.insert(it, 6);it = li.insert(it, 7);for (auto& num : li){cout << num << " ";}return 0;
}

输出结果为:

erase:

int main()
{list<int> li = { 1,2,3,4,5 };list<int>::iterator it = li.begin();it = li.erase(it);for (auto& num : li){cout << num << " ";}return 0;
}

输出结果为:

6.list的其他操作

接下来我们来学习list的其他操作:

函数名称功能描述
splice将元素从一个列表转移到另一个列表
remove移除具有特定值的元素
remove_if移除满足条件的元素
unique移除重复的值
sort对容器中的元素进行排序
merge合并已排序的列表
reverse反转元素的顺序

splice:

splice 是 list 提供的一个成员函数,用于将一个列表(list)中的元素移动到另一个列表中,而不需要进行元素复制或移动操作。

使用示例:

int main()
{list<int> li1 = { 1,2,3 };list<int> li2 = { 4,5,6 };list<int> li3 = { 7,8,9 };list<int> li4 = { 0 };// 将 li2 的所有元素拼接到 li1 的末尾// li1 现在包含 {1, 2, 3, 4, 5, 6}// li2 现在为空 {}li1.splice(li1.end(), li2);for (auto num : li1){cout << num << " ";}cout << endl;// 获取 li3 的迭代器,指向第一个元素(7)auto begin1 = li3.begin();// 将迭代器向前移动一位,指向第二个元素(8)++begin1;// 将 li3 的第一个元素(7)移动到 li4 的末尾// li4 现在包含 {0, 7}// li3 现在包含 {8, 9}li4.splice(li4.end(), li3, li3.begin(), begin1);for (auto num : li4){cout << num << " ";}return 0;
}

输出结果为:

remove:

用于从容器中移除所有等于指定值的元素。

与成员函数 erase 不同,成员函数 erase 按元素的位置擦除元素(使用迭代器),此函数  按元素的值删除元素。

int main()
{list<int> li = { 1,2,3,3,4,5 };li.remove(3);for (auto num : li){cout << num << " ";}cout << endl;return 0;
}

输出结果为:

remove_if:

用于从容器中移除满足特定条件的元素。

bool fun(int num)
{return num == 3;
}int main()
{list<int> li = { 1,2,3,3,4,5 };li.remove_if(fun);for (auto num : li){cout << num << " ";}cout << endl;return 0;
}

输出结果为:

unique:

用于移除容器中连续重复的元素。

int main()
{list<int> li = { 1,2,3,3,4,5 };li.unique();for (auto num : li){cout << num << " ";}return 0;
}

输出结果为:

sort:

用于对容器中的元素进行排序。

int main()
{list<int> li = { 9,1,5,3,2,4,8,0,7,6 };li.sort();for (auto num : li){cout << num << " ";}return 0;
}

输出结果为:

merge:

用于将两个已排序的范围合并成一个有序范围。

要求输入的两个范围必须是有序的(通常是升序)。它会将两个范围中的元素按顺序合并到目标范围中。目标范围必须有足够的空间来存储合并后的结果。

int main()
{list<int> li1 = { 1,3,2,5,7 };list<int> li2 = { 2,3,4,6,8 };li1.sort();li2.sort();li1.merge(li2);for (auto num : li1){cout << num << " ";}return 0;
}

输出结果为:

reverse:

用于反转容器中元素的顺序。

int main()
{list<int> li = { 9,1,5,3,2,4,8,0,7,6 };li.reverse();for (auto num : li){cout << num << " ";}return 0;
}

输出结果为:

二、list与vector的对比

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

结束语

求点赞收藏评论关注!!!

感谢各位大佬的支持!!!

相关文章:

C++——list的了解和使用

目录 引言 forward_list与list 标准库中的list 一、list的常用接口 1.list的迭代器 2.list的初始化 3.list的容量操作 4.list的访问操作 5.list的修改操作 6.list的其他操作 二、list与vector的对比 结束语 引言 本篇博客要介绍的是STL中的list。 求点赞收藏评论…...

移动光猫怎么自己改桥接模式?

环境&#xff1a; 型号H3-8s 问题描述&#xff1a; 家里宽带用的是H3-8s 光猫&#xff0c;想改桥接模式。 解决方案&#xff1a; 1.默认管理员账号和密码&#xff1a; 账号&#xff1a;CMCCAdmin 密码&#xff1a;aDm8H%MdAWEB页面我试了登陆不了&#xff0c;显示错误 …...

jupyter配置说明

使用以下命令修改jupyter的配置文件参数&#xff1a; vim /root/.jupyter/jupyter_lab_config.py #这里填写远程访问的IP名&#xff0c;填*则默认是主机IP名 c.ServerApp.ip * # 这里的密码填写上面生成的密钥 c.ServerApp.password ************************************…...

MiniMax-01中Lightning Attention的由来(线性注意力进化史)

目录 引言原始注意力线性注意力因果模型存在的问题累加求和操作的限制Lightning AttentionLightning Attention-1Lightning Attention-2 备注 引言 MiniMax-01: Scaling Foundation Models with Lightning Attention表明自己是第一个将线性注意力应用到如此大规模的模型&#…...

Vue中的动态组件是什么?如何动态切换组件?

什么是动态组件&#xff1f; 动态组件是 Vue.js 中的一项强大功能&#xff0c;它允许开发者根据程序的状态或用户的操作&#xff0c;动态地切换组件。动态组件的优势在于&#xff0c;开发者可以根据具体需求灵活地渲染不同的组件&#xff0c;从而提高应用的通用性和可维护性。…...

Day33:字符串的切片

在 Python 中&#xff0c;**切片&#xff08;Slicing&#xff09;**是对字符串&#xff08;以及其他序列类型&#xff0c;如列表、元组等&#xff09;进行提取部分内容的强大工具。通过切片&#xff0c;你可以非常方便地提取字符串的子字符串、倒序字符串&#xff0c;甚至进行步…...

汽车网络信息安全-ISO/SAE 21434解析(中)

目录 第七章-分布式网络安全活动 1. 供应商能力评估 2. 报价 3. 网络安全职责界定 第八章-持续的网络安全活动 1. 网路安全监控 2. 网络安全事件评估 3. 漏洞分析 4. 漏洞管理 第九章-概念阶段 1. 对象定义 2. 网路安全目标 3. 网络安全概念 第十章 - 产品开发 第十…...

rust feature h和 workspace相关知识 (十一)

feature 相关作用和描述 在 Rust 中&#xff0c;features&#xff08;特性&#xff09; 是一种控制可选功能和依赖的机制。它允许你在编译时根据不同的需求启用或禁用某些功能&#xff0c;优化构建&#xff0c;甚至改变代码的行为。Rust 的特性使得你可以轻松地为库提供不同的…...

从规则到神经网络:机器翻译技术的演进与未来展望

从规则到神经网络:机器翻译技术的演进与未来展望 引言 还记得早些年用翻译软件翻译一句简单的英文句子,却发现翻译结果让人啼笑皆非的日子吗?从“我喜欢吃苹果”被翻译成“我喜欢吃苹果电脑”,到今天的神经网络机器翻译(Neural Machine Translation, NMT)能够生成语义流…...

LLaMA-Factory 微调LLaMA3

LoRA介绍 LoRA&#xff08;Low-Rank Adaptation&#xff09;是一种用于大模型微调的技术&#xff0c; 通过引入低秩矩阵来减少微调时的参数量。在预训练的模型中&#xff0c; LoRA通过添加两个小矩阵B和A来近似原始的大矩阵ΔW&#xff0c;从而减 少需要更新的参数数量。具体来…...

Debian或Ubuntu系统中重置MySQL的root密码

你提供的步骤是针对在Debian或Ubuntu系统中重置MySQL的root密码的过程。以下是对你提供的步骤的详细说明和补充&#xff1a; 步骤 1.1 - 1.3&#xff1a;进入MySQL配置目录并使用debian-sys-maint账户登录MySQL # 进入MySQL配置目录 cd /etc/mysql/ # 使用vim编辑器打开debia…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.17 时间魔法:处理千万级时间序列的秘籍

1.17 时间魔法&#xff1a;处理千万级时间序列的秘籍 目录 #mermaid-svg-fa6SvjKCpmJ6C2BY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fa6SvjKCpmJ6C2BY .error-icon{fill:#552222;}#mermaid-svg-fa6SvjKCpmJ6…...

WPS数据分析000009

一、函数与数据透视表统计数据时效率差异 函数 F4绝对引用 数据透视表 二、数据透视表基础操作 数据透视表&#xff1a;一个快速的生成报表的工具 显示详细信息 方式一; 方式二&#xff1a; 移动数据透视表 删除数据透视表 复制粘贴数据透视表 留足空间&#xff0c;否则拖动字…...

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…...

K8S 快速实战

K8S 核心架构原理: 我们已经知道了 K8S 的核心功能:自动化运维管理多个容器化程序。那么 K8S 怎么做到的呢?这里,我们从宏观架构上来学习 K8S 的设计思想。首先看下图: K8S 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责核心的调度、管理和运维,Slave…...

用Python和PyQt5打造一个股票涨幅统计工具

在当今的金融市场中&#xff0c;股票数据的实时获取和分析是投资者和金融从业者的核心需求之一。无论是个人投资者还是专业机构&#xff0c;都需要一个高效的工具来帮助他们快速获取股票数据并进行分析。本文将带你一步步用Python和PyQt5打造一个股票涨幅统计工具&#xff0c;不…...

linux naive代理设置

naive linux客户端 Release v132.0.6834.79-2 klzgrad/naiveproxy GitHub Client setup Run ./naive with the following config.json to get a SOCKS5 proxy at local port 1080. {"listen": "socks://127.0.0.1:1080","proxy": "htt…...

猿人学第一题 js混淆源码乱码

首先检查刷新网络可知&#xff0c;m参数被加密&#xff0c;这是一个ajax请求 那么我们直接去定位该路径 定位成功 观察堆栈之后可以分析出来这应该是一个混淆&#xff0c;我们放到解码平台去还原一下 window["url"] "/api/match/1";request function…...

【学术会议征稿】第五届能源、电力与先进热力系统学术会议(EPATS 2025)

能源、电力与先进热力系统设计是指结合物理理论、工程技术和计算机模拟&#xff0c;对能源转换、利用和传输过程进行设计的学科领域。它涵盖了从能源的生产到最终的利用整个流程&#xff0c;旨在提高能源利用效率&#xff0c;减少能源消耗和环境污染。 重要信息 官网&#xf…...

对神经网络基础的理解

目录 一、《python神经网络编程》 二、一些粗浅的认识 1&#xff09; 神经网络也是一种拟合 2&#xff09;神经网络不是真的大脑 3&#xff09;网络构建需要反复迭代 三、数字图像识别的实现思路 1&#xff09;建立一个神经网络类 2&#xff09;权重更新的具体实现 3&am…...

.strip()用法

.strip("") 是 Python 字符串方法 strip() 的一个用法&#xff0c;它会去除字符串两端指定字符集中的字符。 基本语法&#xff1a; string.strip([chars])string: 这是你要操作的字符串。chars: 可选参数&#xff0c;表示你想要去除的字符集&#xff08;默认为空格…...

redis的分片集群模式

redis的分片集群模式 1 主从哨兵集群的问题和分片集群特点 主从哨兵集群可应对高并发写和高可用性&#xff0c;但是还有2个问题没有解决&#xff1a; &#xff08;1&#xff09;海量数据存储 &#xff08;2&#xff09;高并发写的问题 使用分片集群可解决&#xff0c;分片集群…...

【29】Word:李楠-学术期刊❗

目录 题目​ NO1.2.3.4.5 NO6.7.8 NO9.10.11 NO12.13.14.15 NO16 题目 NO1.2.3.4.5 另存为手动/F12Fn光标来到开头位置处→插入→封面→选择花丝→根据样例图片&#xff0c;对应位置填入对应文字 (手动调整即可&#xff09;复制样式&#xff1a;开始→样式对话框→管理…...

基于 AI Coding 「RTC + STT」 Web Demo

文章目录 1. 写在最前面1.1 旧测试流程1.2 新测试流程 2. Cursor 编程 vs Copilot 编程2.1 coding 速度2.2 coding 正确性 3. 碎碎念 1. 写在最前面 为了 Fix 语音转文字&#xff08;STT&#xff09;产品在 Json 协议支持上的问题&#xff0c;笔者需要将推送到 RTC 的数据按照…...

doris:Parquet导入数据

本文介绍如何在 Doris 中导入 Parquet 格式的数据文件。 支持的导入方式​ 以下导入方式支持 Parquet 格式的数据导入&#xff1a; Stream LoadBroker LoadINSERT INTO FROM S3 TVFINSERT INTO FROM HDFS TVF 使用示例​ 本节展示了不同导入方式下的 Parquet 格式使用方法…...

L2TP使用举例

下面是一个使用C和POSIX套接字API实现L2TP协议的简单示例。这个示例展示了如何创建一个L2TP客户端&#xff0c;连接到L2TP服务器并发送数据。请注意&#xff0c;这只是一个基本的示例&#xff0c;实际的L2TP实现会更复杂&#xff0c;通常需要处理更多的协议细节和错误处理。 L…...

dup2 + fgets + printf 实现文件拷贝

思路 将源文件的内容读取到内存中&#xff0c;然后将这些内容写入到目标文件。 1: 打开源文件、目标文件 fopen() 以读模式打开源文件。 open ()以写模式打开目标文件。 2: 读取源文件、写入目标文件 fgets ()从源文件中读取内容。 printf ()将内容写入目标文件。 printf…...

实验六 带函数查询和综合查询(1)

实验六 带函数查询和综合查询&#xff08;1&#xff09; 一、实验目的 1&#xff0e;掌握Management Studio的使用。 2&#xff0e;掌握带函数查询和综合查询的使用。 二、实验内容及要求 1统计年龄大于30岁的学生的人数。 select count(*) from student where year(getdate…...

塔罗牌(基础):大阿卡那牌

塔罗牌&#xff08;基础&#xff09; 大啊卡那牌魔术师女祭司皇后皇帝教皇恋人战车力量隐士命运之轮正义吊人死神节制恶魔高塔星星月亮太阳审判世界 大啊卡那牌 魔术师 作为一个起点&#xff0c;象征&#xff1a;意识行动和创造力。 一个【显化】的概念&#xff0c;即是想法变…...

LLM大模型推理中的常见数字

1. 聊天机器人Chatbot&#xff0c;一般&#xff0c;input tokens : output tokens 1100:15 2. LLama2的tokenizer&#xff0c;中文情况下&#xff0c;token:汉字1:1.01 3. prefilling阶段的吞吐量(tokens/s)&#xff0c;一般是decoding阶段的50~100倍。 4. 4张带有NVLink的…...