C++初阶(十五)--STL--list 的深度解析与全面应用

news2024/11/25 16:26:42

文章目录

一、头文件与基本概念

二、构造函数和析构函数

1.构造函数

2.析构函数

三、元素访问

front

back

四、迭代器相关函数

begin

end

rebegin(反向迭代器)

rend(反向迭代器)

五、容量相关函数

empty

size

max_size

六、修改器

assign

push_front 

push_back

pop_front

pop_back 

insert 

erase 

swap

clear

resize

七、操作

merge 

splice

remove

remove_if

reserve 

sort

unique

emplace函数(C++11及以上)

八、非成员函数重载

1.比较运算符重载(==、!=、<、<=、>、>=)

2.swap 函数(非成员函数重载)


C++ 的标准模板库(STL)中的 list 是一个功能强大且灵活的双向链表容器,它提供了众多接口函数来满足各种编程需求。在本篇博客中,我们将深入探讨 list 的所有成员函数,包括一些相对不太常用但在特定场景下非常有用的函数,我们这里只探讨基本的使用,不探讨底层原理,下一篇博客,我们将会模拟实现list。

一、头文件与基本概念

要使用list容器,首先需要包含<list>头文件,并引入std命名空间,使得我们可以直接使用list而不是std::list

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

list 作为双向链表容器,其每个节点包含数据以及指向前一个节点和后一个节点的指针,这使得它在插入和删除操作上具有独特的优势,但在随机访问方面相对较弱。

二、构造函数和析构函数

1.构造函数

默认构造函数:创建一个空的list容器

list<int> myList1;

填充构造函数:构造一个含有n个val的某类型容器。

	list<int> myList2(10, 2);

初始化列表构造函数:使用给定的初始化列表来初始化list

list<int> myList3 = { 1, 2, 3, 4, 5 };

拷贝构造函数:用另一个同类型的 list 容器来初始化新的 list

list<int> myList4(myList1);

范围构造函数:依据其他容器(如数组、vector 等)中指定范围的元素构建 list。例如,假设有数组 int arr[] = {6, 7, 8, 9, 10};

list<int> myList4(arr, arr + 5);

移动构造函数(C++11及以上):允许将一个临时 list 资源转移到新创建的 list 中,以提高性能。例如:

list<int> createTempList()
{
	list<int> temp = { 11, 12, 13 };
	return temp;
}

list<int> myList6 = createTempList();  // 使用移动构造函数初始化 myList6

2.析构函数

当 list 容器对象超出作用域或被显式删除时,析构函数会自动被调用,释放链表中每个节点所占用的内存资源,确保内存不会泄漏。

三、元素访问

front

作用:返回list容器中的第一个元素

cout << "第一个元素: " << myList2.front() << endl;

back

作用:返回list容器中的最后一个元素

cout << "最后一个元素: " << myList2.back() << endl;

四、迭代器相关函数

begin

返回指向list容器中第一个元素的正向迭代器,通过这个迭代器可以顺序遍历容器中的元素

list<int>::iterator itBegin = myList2.begin();

end

返回指向list容器中最后一个元素之后位置的正向迭代器,用于标记整形遍历的结束。

list<int>::iterator itEnd = myList2.end();

rebegin(反向迭代器)

返回指向list容器中最后一个元素的反向迭代器,可用于从后向前遍历容器

list<int>::reverse_iterator itRBegin = myList2.rbegin();

rend(反向迭代器)

返回指向list容器中第一个元素之前位置的反向迭代器,标记反向遍历的结束。

list<int>::reverse_iterator itREnd = myList2.rend();

五、容量相关函数

empty

检查list容器是否为空,为空时返回true,否则返回false。

if (myList1.empty()) {
    cout << "myList1 为空" << endl;
} else {
    cout << "myList1 不为空" << endl;
}

size

返回list容器中当前元素的数量。

cout << "myList2 的元素个数: " << myList2.size() << endl;

max_size

返回list容器理论上能够容纳的最大元素数量,这个数量通常取决于系统资源和实现细节。

cout << "myList2 最大可容纳元素数: " << myList2.max_size() << endl;

六、修改器

assign

使用新的元素替换list容器中的所有现有元素。

myList2.assign(3, 100);  // 将 myList2 中的元素替换为 3 个 100

也可以使用一个范围的元素来进行替换,假设存在另一个list: list<int> otherList = {200,300,400};

list<int> otherList = { 200,300,400 };
myList1.assign(otherList.begin(), otherList.end());

push_front 

在list容器的头部插入一个新元素。

myList2.push_front(0);

push_back

在list容器的尾部插入一个新元素。

myList.push_back(6);

pop_front

移除 list 容器头部的元素。

myList2.pop_front();

pop_back 

移除 list 容器尾部的元素

myList2.pop_back();

insert 

在指定位置插入一个元素,列如,在myList2的第二个位置插入值为15的元素。

auto itInsertPos = myList2.begin();
++itInsertPos;
myList2.insert(itInsertPos, 15);

也可以一次性插入多个相同元素,如在myList的开头插入3个值为5的元素:

myList2.insert(myList2.begin(), 3, 5);

也可以插入一个范围的元素,假设有 vector<int> vec = {7,8,9}。

myList2.insert(myList2.end(), vec.begin(), vec.end());

erase 

移除指定位置的元素。列如,移除myList2中的第三个元素。

auto itErasePos = myList2.begin();
++itErasePos;
++itErasePos;
myList2.erase(itErasePos);

也可以移除一个范围的元素,如移除myList2中的第二个元素到第四个元素(不包括第四个)。

auto start = myList2.begin();
++start;
auto end = start;
++end;
++end;
myList2.erase(start, end);

swap

交换两个 list容器的内容

list<int> listA = {1, 2, 3};
list<int> listB = {4, 5, 6};
listA.swap(listB);

clear

移除list容器中的所有元素,使其变为空容器

myList2.clear();

resize

两种情况:

  1. 当所给值大于当前的size时,将size扩大到该值,扩大的数据为第二个所给值,若未给出,则默认为容器所存储类型的默认构造函数所构造出来的值。
  2. 当所给值小于当前的size时,将size缩小到该值。
myList1.resize(10);  // 将 myList1 大小调整为 10,新增元素使用默认值初始化

myList1.resize(5);  // 将 myList1 大小调整为 5,移除后面的元素

myList1.resize(8, 20);  // 将 myList1 大小调整为 8,新增元素值为 20

七、操作

merge 

将另一个已排序的 list 合并到当前 list 中,合并后当前 list 仍保持有序。假设 list<int> listC = {1, 3, 5}; 和 list<int> listD = {2, 4, 6};,且 listC 和 listD 都已排序。

listC.merge(listD);

splice

将另一个list中的一个或多个元素移动到当前list的指定位置,列如,将 listD 的所有元素移动到 listC 的开头。

listC.splice(listC.begin(), listD);

也可以移动指定位置的单个元素,假设有 list<int> listE = {10,20,30}。

auto itE = listE.begin();
++itE;
listC.splice(listC.begin(), listE, itE);

remove

移除list容器中所有与指定值相等的元素

myList2.remove(2);

remove_if

根据指定的谓词(函数或函数对象)移除满足条件的元素。例如,移除所有偶数元素。

list<int> listG = { 1, 2, 3, 4, 5, 6 };
listG.remove_if([](int x) { return x % 2 == 0; });//去除偶数

reserve 

反转list容器中元素的顺序

list<int> listH = {1, 2, 3, 4, 5};
listH.reverse();

sort

对 list 容器中的元素进行排序。默认按照升序排序,如果需要自定义排序规则,可以传入比较函数或函数对象。例如,按照降序排序,需要按照以下代码写。

list<int> listI = {5, 3, 4, 1, 2};
listI.sort(greater<int>());

unique

移除list容器中连续的重复元素,只保留一个。

list<int> listJ = {1, 1, 2, 2, 3, 3, 3, 4, 4};
listJ.unique();

emplace函数(C++11及以上)

在指定位置原地构造一个新元素,相比于 insert 函数,emplace 函数可以避免不必要的临时对象创建和复制,提高效率。例如,在 list 开头插入一个值为 100 的元素:

myList2.emplace(myList2.begin(), 100);

八、非成员函数重载

1.比较运算符重载==!=<<=>>=

可以直接比较两个 list 容器是否相等或确定它们的大小关系,比较基于元素的逐对比较。例如:

list<int> listK = {1, 2, 3};
list<int> listL = {1, 2, 3};
if (listK == listL) {
    cout << "listK 和 listL 相等" << endl;
}

2.swap 函数(非成员函数重载)

提供了一种更方便的方式来交换两个 list 容器的内容,与成员函数 swap 功能相同,但调用方式略有不同。

list<int> listM = {4, 5, 6};
list<int> listN = {7, 8, 9};
swap(listM, listN);

 

本篇博客到此结束,欢迎评论区留言~


本篇博客参考资料网址:cplusplus.com

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

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

相关文章

企业数智化新纪元,安全体系保驾护航

随着云计算、大数据、人工智能等技术的不断发展成熟&#xff0c;企业数智化建设进入到了深水区&#xff0c;网络安全已经成为企业发展最重要的基石。企业如何更好地拥抱先进生产力、构建强大的安全体系、重塑企业核心竞争力&#xff0c;是每一位技术决策者需要认真思考和解决的…

学Linux的第九天--磁盘管理

目录 一、磁盘简介 &#xff08;一&#xff09;、认知磁盘 &#xff08;1&#xff09;结构 &#xff08;2&#xff09;物理设备的命名规则 &#xff08;二&#xff09;、磁盘分区方式 MBR分区 MBR分区类型 扩展 GPT格式 lsblk命令 使用fdisk管理分区 使用gdisk管理分…

QT实现拷贝复制文件操作 QT5.12.3环境 C++实现

案例需求&#xff1a;利用QT线程操作&#xff0c;实现拷贝复制文件操作 代码&#xff1a; myfile.h #ifndef MYFILE_H #define MYFILE_H#include <QObject> #include <QDebug> #include <QThread> #include <QFile> #include <QtWidgets> class…

IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)

汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea&#xff0c;找到连接中 文件&#xff0c;卸载即可。

Jenkins-Git Parameter 插件实现指定版本的发布和回滚

在上一篇文章的基础设置上进行 1. 机器准备 开发10.0.0.204gitlab10.0.0.201jenkins10.0.0.200web10.0.0.202 2. 开发主机 在开发机器上修改不同版本的前端页面&#xff0c;并打上标签 第一次修改 [rootdev wheel]#vim index.html [rootdev wheel]#git commit -am "1…

Ubuntu ESP32开发环境搭建

文章目录 ESP32开发环境搭建安装ESP-IDF搭建一个最小工程现象 ESP32开发环境搭建 最近有个小项目需要用到能够联网的mcu驱动&#xff0c;准备玩玩esp的芯片&#xff0c;记录下ESP32开发环境搭建的过程。 ESP-IDF 是乐鑫科技为其 ESP32 系列芯片提供的官方开发框架。这个框架主…

《剖析 Spring 原理:深入源码的旅程(二)》

六、Spring 的 Bean 注入与装配 Spring 的 Bean 注入与装配的方式有很多种&#xff0c;可以通过 xml、get set 方式、构造函数或者注解等。简单易用的方式就是使用 Spring 的注解&#xff0c;Spring 提供了大量的注解方式&#xff0c;如 Autowired、Qualifier 等。Spring 还支持…

Git的使用_仓库管理_CI/CD介绍

文章目录 一、Git的基础知识一-1、什么是GitLinux命令行的git的简易安装Git项目的组成Git的基本工作流程Git文件的三种状态 一-2、存储库远程存储库与本地存储库创建存储库git init命令的使用方法1. 初始化一个新的 Git 仓库2. 在指定目录初始化一个新的 Git 仓库3. 初始化一个…

Android 实现悬浮球的功能

Android 实现悬浮球的功能 在 Android 中&#xff0c;实现悬浮球可以通过以下方式实现&#xff0c;常见的方法是使用 WindowManager 创建一个悬浮窗口。以下是具体的实现步骤&#xff1a; 1. 配置权限 在 AndroidManifest.xml 中添加悬浮窗权限&#xff1a; <uses-permis…

C语言数据结构学习:循环队列

C语言 数据结构学习 汇总入口&#xff1a; C语言数据结构学习&#xff1a;[汇总] 1. 循环队列 队列的博客&#xff1a;C语言数据结构学习&#xff1a;队列 循环队列会预先定义最大队列空间&#xff0c;然后定义一个数组&#xff0c;通过队列头和队列尾指针分别指向开头和结尾&…

Java教程:SE进阶【十万字详解】(下)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

37_U-Net网络详解

1.U-Net 网络概述 U-Net 是一种深度学习模型&#xff0c;广泛用于图像的语义分割任务。U-Net 网络的结构特别适合医学影像分割&#xff0c;尤其在少量训练数据的情况下表现优异。该网络由一个编码器-解码器架构组成&#xff0c;具有对称的“U”形结构&#xff0c;因此得名为 U…

mysql-分析MVCC原理

一、MVCC简介 MVCC是一种用来解决读写冲读的无锁并发控制&#xff0c;也就是为事务分配单增长的时间戳&#xff0c;为每个修改保存一个版本&#xff0c;版本与事务时间戳关联&#xff0c;读操作只读该事务开始前的数据库的快照&#xff0c;所以MVCC可以为数据库解决一些问题。…

【CSP CCF记录】201812-2第15次认证 小明放学

题目 样例1输入 30 3 30 8 0 10 1 5 0 11 2 2 0 6 0 3 3 10 0 3 样例1输出 30 3 30 8 0 10 1 5 0 11 2 2 0 6 0 3 3 10 0 3 思路 参考&#xff1a;CCF小白刷题之路---201812-2 小明放学&#xff08;C/C 100分&#xff09;_小明放学测试数据-CSDN博客 我们使用一个for循环计算…

Kafka 分区分配及再平衡策略深度解析与消费者事务和数据积压的简单介绍

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

计算机网络-VPN虚拟专用网络概述

前面我们学习了在企业内部的二层交换机网络、三层路由网络包括静态路由、OSPF、IS-IS、NAT等&#xff0c;现在开始学习下VPN&#xff08;Virtual Private Network&#xff0c;虚拟专用网络&#xff09;&#xff0c;其实VPN可能很多人听到第一反应就是梯子&#xff0c;但是其实这…

《第十部分》1.STM32之通信接口《精讲》之IIC通信---介绍

经过近一周的USART学习&#xff0c;我深刻体会到通信对单片机的重要性。它就像人类的手脚和大脑&#xff0c;只有掌握了通信技术&#xff0c;单片机才能与外界交互&#xff0c;展现出丰富多彩的功能&#xff0c;变得更加强大和实用。 单片机最基础的“语言”是二进制。可惜&am…

【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;前言&#x1f4af;C 语言与 C 语言的输入输出对比1.1 C 语言的输入输出1.2 C 语言的输入输出 &#x1f4af; std::ios::sync_with_stdio(false) 的作用与意义2.1 什么是 std::ios::s…

初识Linux—— 基本指令(下)

前言&#xff1a; 本篇继续来学习Linux的基础指令&#xff0c;继续加油&#xff01;&#xff01;&#xff01; 本篇文章对于图片即内容详解&#xff0c;已同步到本人gitee&#xff1a;Linux学习: Linux学习与知识讲解 Linux指令 1、查看文件内容的指令 cat ​ cat 查看文件…

VM虚拟机装MAC后无法联网,如何解决?

✨在vm虚拟机上&#xff0c;给虚拟机MacOS设置网络适配器。选择NAT模式用于共享主机的IP地址 ✨在MacOS设置中设置网络 以太网 使用DHCP ✨回到本地电脑上&#xff0c;打开 服务&#xff0c;找到VMware DHCP和VMware NAT&#xff0c;把这两个服务打开&#xff0c;专一般问题就…