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

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使用指定列表替换原列表

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

尾删和尾插:

输出结果为:

头删和头插:

输出结果为:

assign和swap:

输出结果为:

insert:

输出结果为:

erase:

输出结果为:

6.list的其他操作

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

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

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


使用示例:

输出结果为:

remove:

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

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


输出结果为:

remove_if:

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


输出结果为:

unique:

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


输出结果为:

sort:

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


输出结果为:

merge:

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

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

输出结果为:

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)
空间利用率底层为连续空间,不容易造成内存碎片,空间利用率高,缓存利用率高底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低
迭代器原生态指针对原生态指针(节点指针)进行封装
迭代器失效在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来迭代器失效,删除时,当前迭代器需要重新赋值否则会失效插入元素不会导致选代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响
使用场景需要高效存储,支持随机访问,不关心插入删除效率大量插入和删除操作,不关心随机访问

结束语

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

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

Read more

AI之MLMs之Tool:Open Notebook的简介、安装和使用方法、案例应用之详细攻略

AI之MLMs之Tool:Open Notebook的简介、安装和使用方法、案例应用之详细攻略

AI之MLMs之Tool:Open Notebook的简介、安装和使用方法、案例应用之详细攻略 目录 Open Notebook的简介 1、特点 (1)、与 Google Notebook LM 的核心优势对比 (2)、核心功能 (Core Capabilities) (3)、高级功能 (Advanced Features) Open Notebook的安装和使用方法 1、安装 1.1、准备工作 1.2、安装步骤 方法一:使用 Docker 命令 (适用于本地或远程服务器) 方法二:使用 Docker Compose (推荐,便于管理) 1.3、关键设置说明 2、使用方法

By Ne0inhk
AI Agent 架构:基础组成模块深度解析

AI Agent 架构:基础组成模块深度解析

AI Agent 架构:基础组成模块深度解析 📝 本章学习目标:本章是入门认知部分,帮助零基础读者建立对AI Agent的初步认知。通过本章学习,你将全面掌握"AI Agent 架构:基础组成模块深度解析"这一核心主题。 一、引言:为什么这个话题如此重要 在AI Agent快速发展的今天,AI Agent 架构:基础组成模块深度解析已经成为每个开发者和研究者必须了解的核心知识。无论你是技术背景还是非技术背景,理解这一概念都将帮助你更好地把握AI时代的机遇。 1.1 背景与意义 💡 核心认知:AI Agent正在从"对话工具"进化为"执行引擎",能够主动完成任务、调用工具、与外部世界交互。这一变革正在深刻改变我们的工作和生活方式。 从2023年AutoGPT的横空出世,到如今百花齐放的Agent生态,短短一年多时间,执行式AI已经从概念走向落地。根据最新统计,

By Ne0inhk
task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code

task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code

task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code 背景 之前一直没有动手处理 AI 编程软件的事情,一直还停留在拉取 github 然后本地安装的“刻板映像”中,而实际情况是在我拥有 AI-IDE 窗口之后,很多工具都可以互相接通,所以我从最开始下载cursor 安装,逐渐转换为cursor 只是我的一个窗口,最终目的是用 安装Claude code。 描述 认知跃迁,从“本地安装工具”的静态思维 → 转向“AI-IDE 为统一入口”的动态集成范式。本质是将 Cursor 视为「AI 编程操作系统」的 Shell,而非终点。核心转变:工具即服务,窗口即接口。 准备怎么干 摸黑开始,

By Ne0inhk
内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解

内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解

🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:未来思考,本专栏结合当前国家战略和实时政治,对未来行业发展的思考 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 🔥内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解 |前言| 最近装机的小伙伴们欲哭无泪:DDR5内存价格一路狂飙,部分DRAM现货价格在过去一年暴涨近700% 。大家习惯性吐槽“厂商放火”、“产能不足”,但很少有人看到,这场涨价风暴的真正推手,是那只名为“AI”的巨兽。 当你还在为多花几百块钱买内存心疼时,国家正在西部荒漠建起一座座数据中心,科技巨头正在为“吃电怪兽”抢购每一颗芯片。2026年,大型科技公司的AI相关投资预计将达到6500亿美元,较去年增长约80% 。 今天,我们从能源供应、隐私安全、绿色AI 三个维度,结合东数西算、算电协同、

By Ne0inhk