【C++】 List 基本使用

news2024/9/23 7:32:02

C++ List 基本使用

基本概念

list 是一个序列容器,它内部维护了一个双向链表结构。与 vectordeque 等基于数组的容器不同,list 在插入和删除元素时不需要移动大量数据,因此在这些操作上具有较高的效率。然而,访问列表中的特定元素通常需要线性时间,因为 list 不提供随机访问迭代器。

list 动态分配内存,每个元素作为一个独立的节点,节点之间通过指针链接,这种结构使得插入和删除操作非常高效。

插入和删除操作

list 提供了多种插入和删除元素的方法,如 push_front, push_back, pop_front, pop_back, insert, erase 等,这些操作通常具有常数时间复杂度 O(1)。

list<int> lst;
lst.push_front(1); // 在列表前端插入元素
lst.push_back(2); // 在列表尾端插入元素
lst.insert(lst.begin(), 0); // 在迭代器指定位置插入元素
lst.erase(lst.begin()); // 删除迭代器指向的元素
lst.pop_front(); // 删除并返回列表前端的元素
lst.pop_back(); // 删除并返回列表尾端的元素
迭代器

list 提供双向迭代器,允许从任意方向遍历列表,而且在插入或删除元素时迭代器保持有效,这是与基于数组的容器如 vector 的主要区别之一。

典型用法

创建和初始化
#include <list>
#include <iostream>

int main() {
    list<int> lst; // 创建一个空列表
    list<int> lst2{1, 2, 3}; // 列表初始化
    list<int> lst3(lst2.begin(), lst2.end()); // 区间初始化
    list<int> lst4 = {4, 5, 6}; // 嵌入式初始化
    return 0;
}
遍历列表
list<int> lst = {1, 2, 3};
for (auto it = lst.begin(); it != lst.end(); ++it) {
    cout << *it << ' ';
}
// 或者使用范围for循环
for (const auto& elem : lst) {
    cout << elem << ' ';
}

常用操作

方法描述
insert()它将新元素插入到迭代器指向的位置之前。
push_back()它在容器的末尾添加了一个新元素。
push_front()它在前面增加了一个新元素。
pop_back()删除最后一个元素。
pop_front()删除第一个元素。
empty()它检查列表是否为空。
size()它查找列表中存在的元素数。
max_size()它找到列表的最大大小。
front()它返回列表的第一个元素。
back()它返回列表的最后一个元素。
swap()当两个列表的类型相同时,它将交换两个列表。
reverse()它反转了列表的元素。
sort()它以递增的顺序对列表中的元素进行排序。
merge()它合并两个排序的列表。
splice()它将新列表插入到调用列表中。
unique()它从列表中删除所有重复的元素。
resize()它更改列表容器的大小。
assign()它将一个新元素分配给列表容器。
emplace()它将在指定位置插入一个新元素。
emplace_back()它将在容器的末尾插入一个新元素。
emplace_front()它将在列表的开头插入一个新元素。

性能考量

虽然 list 在插入和删除方面表现出色,但由于不支持随机访问,因此在需要频繁随机访问元素的场景中,vectordeque 可能是更佳选择。

vector vs list 深入解析与对比

内部结构
  • vector: 基于动态数组实现,优点:支持快速地通过索引随机访问任何元素很好的支持排序、二分查找、堆算法,时间复杂度为O(1)缺点:插入或删除头部元素时效率较低最坏时间复杂度为O(n),且空间不够后增容的代价较大。
  • list: 是一个带头双向循环链表,优点:每个元素都是链表中的一个节点,节点之间通过指针连接。使得插入和删除操作在任何位置都非常高效,时间复杂度为O(1)缺点:不支持随机访问,访问列表中的特定元素需要从头或尾遍历,最坏时间复杂度为O(n)。
迭代器行为
  • vector:当vector容量不足以容纳新的元素时,它会重新分配内存,将所有元素复制到新的内存空间。这个过程会使得之前所有指向vector的迭代器失效。
  • list:迭代器在大多数情况下保持有效。只有当列表中的元素被删除或迭代器被显示重置时,受影响的迭代器才会失效。因为list中的元素都是独立的节点,插入删除操作只需要更新指针指向,不会影响其他节点的地址。
选择场景
  • vector:适用于需要频繁随机访问元素,且主要在容器尾部进行插入和删除操作的场景。
  • list:适用于需要在容器任意位置高效插入和删除元素的场景,特别是在插入和删除操作频率高于随机访问的情况下。

vectorlist是两个相辅相成互补的容器。

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

vector示例:

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

int main() {
    std::vector<int> vec = { 1, 2, 3 };
	vec.push_back(4); // 在末尾插入元素
	cout << vec[2] << endl; // 随机访问元素

	auto it = vec.begin() + 2; // 创建指向第3个元素的迭代器
	cout << "头插前:" << *it << endl;

	// 在向量开始插入元素
	vec.insert(vec.begin(), 0);

	// 此时,原先的迭代器it已失效,因为所有的元素都向后移动了一位
	// 下面的代码将触发未定义的行为
	// cout << "头插后:" << *it << std::endl;

	// 正确的做法是重新定位迭代器
	it = vec.insert(vec.begin(), 9); // 利用函数返回值重新指向有效迭代器

	cout << "头插后:" << *it << endl;
    return 0;
}

list示例:

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

int main() {
    list<int> lst = {1, 2, 3};
    lst.push_front(0); // 在开头插入元素,迭代器有效
    // 让迭代器指向第一个元素
    auto it = lst.begin();
    cout << "插入前:" << *it << endl;
    lst.insert(lst.begin(), 4); // 在任意位置插入元素,迭代器有效
    cout << "插入前:" << *it << endl;
    
    return 0;
}

wallhaven-x63j9v

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

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

相关文章

公共资源管理服务中心智能化方案PPT(97页)

公共资源管理服务中心智能化方案摘要 1. 建设背景及需求 公共资源管理服务中心的建设以便民、高效、廉洁、规范为宗旨&#xff0c;推行“一站式办公、一条龙服务、并联式审批、阳光下作业、规范化管理”的运行模式。目标是提高行政效率和社会效益&#xff0c;预防流程漏洞&am…

硬盘HDD:AI时代的战略金矿?

在这个AI如火如荼的时代&#xff0c;你可能以为硬盘HDD已经像那些过时的诺基亚手机一样&#xff0c;被闪存和云存储淘汰到历史的尘埃里。但&#xff0c;别急着给HDD们举行退休派对&#xff0c;因为根据Finis Conner这位硬盘界的传奇人物的说法&#xff0c;它们非但没退场&#…

旋转电连接器抗干扰性有哪几个方面?

旋转电连接器作为一种精密的电气传输装置&#xff0c;它实现了两个相对旋转部件间的功率和信号传输。通过旋转电连接器可以传输高频的交流电、高电压的交流电、大电流的交流电、弱小的直流小信号等多种电信号&#xff0c;但是由仪器之间的距离有限&#xff0c;在如此短的距离内…

C 语言结构体

本博客涉及的结构体知识有&#xff1a; 1.0&#xff1a;结构体的创建和使用 2.0: typedef 关键字与#define 关键字的区别 3.0: 结构体成员的访问【地址访问与成员访问】 4.0: 结构体嵌套调用 5.0 数组访问赋值结构体成员 ...... 1.0&#xff1a;结构体的创建和使用 结…

33.异步FIFO IP核的配置、调用与仿真

&#xff08;1&#xff09;异步FIFO的配置过程&#xff1a; ps&#xff1a;异步fifo相比较同步fifo少一个实际深度 &#xff08;2&#xff09;异步FIFO的调用: module dcfifo (input wr_clk ,input rd_clk ,input [7:0] …

LT_0001_两数之和

一、题目描述 二、代码实现 2.1 暴力枚举 时间复杂度O(N^2) public static int[] towSum(int[] nums, int target) {for (int i 0; i < nums.length; i) {for (int j i 1; j < nums.length; j) {if (nums[i] nums[j] target) {return new int[]{i,j};}}}return n…

github actions方式拉取docker镜像

参考&#xff1a; https://wkdaily.cpolar.cn/archives/gc 注意github actions提供的免费虚拟机空间有限&#xff0c;空间不足会报错&#xff0c;查看大概语句有10来G 我在workflow file里加了df -h 运行查看磁盘情况&#xff1a; 通过pwd命令&#xff0c;可以知道运行目录/ho…

护网HW面试——redis利用方式即复现

参考&#xff1a;https://xz.aliyun.com/t/13071 面试中经常会问到ssrf的打法&#xff0c;讲到ssrf那么就会讲到配合打内网的redis&#xff0c;本篇就介绍redis的打法。 未授权 原理&#xff1a; Redis默认情况下&#xff0c;会绑定在0.0.0.0:6379&#xff0c;如果没有采用相关…

自然语言处理(NLP)——法国工程师IMT联盟 期末考试题

1. 问题1 &#xff08;法语&#xff09;En langue arabe lcrasante majorit des mots sont forms par des combinaisons de racines et de schmes. Dans ce mcanisme... &#xff08;英语&#xff09;In Arabic language the vast majority&#xff08;十之八九&#xff09; of…

JAVA自定义注释

interface 声明 package test; public interface InProgress { } InProgress public void calculateInterest(float amount, float rate) { } 带成员 public interface TODO {String value(); } InProgress //只有成员变量名有value时&#xff0c;值有给value赋值时可以这…

水的几个科学问题及引发的思考

水的几个科学问题及引发的思考 1、两个相同的容器A和B&#xff0c;分别装有同质量的水&#xff0c;然后&#xff0c;在A容器中加入水&#xff0c;在B容器中加入冰&#xff0c;如果加入水和冰的质量相同。问&#xff0c;容器B的水位将与容器A的水位相同吗&#xff08;假设冰未融…

Web 性能入门指南-1.5 创建 Web 性能优化文化的最佳实践

最成功的网站都有什么共同点&#xff1f;那就是他们都有很强的网站性能和可用性文化。以下是一些经过验证的有效技巧和最佳实践&#xff0c;可帮助您建立健康、快乐、值得庆祝的性能文化。 创建强大的性能优化文化意味着在你的公司或团队中创建一个如下所示的反馈循环&#xff…

永磁同步电机控制算法--基于 SVM 的无磁链环 DTC

永磁同步电机无磁链环 DTC 通过控制定子磁链交轴分量来直接控制转矩&#xff0c;不再要求控制磁链幅值恒定&#xff0c;省去了传统 DTC 中的磁链环&#xff0c;不仅转矩响应更快&#xff0c;有效抑制了转矩脉动&#xff0c;而且提高了电机功率因数。但无磁链环 DTC 方案仍采用传…

探索4D毫米波雷达和摄像头在自动驾驶中的潜力

随着自动驾驶技术的快速发展&#xff0c;关于各种传感器的必要性&#xff0c;尤其是LiDAR&#xff08;激光雷达&#xff09;与毫米波雷达结合摄像头的作用&#xff0c;激发了激烈的讨论。在这篇博客中&#xff0c;我们将探讨4D毫米波雷达和摄像头的组合是否可能成为自动驾驶车辆…

python爬虫网页解析模块及测试案例详解

xpath模块 xpath模块基本使用方法 测试网页 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"/><title>Title</title> </head> <body><ul><li id"l1" class"c1&q…

R语言安装devtools包失败过程总结

R语言安装devtools包时&#xff0c;遇到usethis包总是安装失败&#xff0c;现总结如下方法&#xff0c;亲测可有效 一、usethis包及cli包安装问题 首先&#xff0c;Install.packages("usethis")出现如下错误&#xff0c;定位到是这个cli包出现问题 载入需要的程辑包…

GESP CCF C++ 四级认证真题 2024年6月

第 1 题 下列代码中&#xff0c;输出结果是&#xff08; &#xff09; A. 12 24 24 12 B. 24 12 12 24 C. 12 12 24 24 D. 24 24 12 12 第 2 题 下面函数不能正常执行的是&#xff08;&#xff09; A. B. C. D. 第 3 题 下面程序…

博客前端项目学习day01

这里写自定义目录标题 登录创建项目配置环境变量&#xff0c;方便使用登录页面验证码登陆表单 在VScode上写前端&#xff0c;采用vue3。 登录 创建项目 检查node版本 node -v 创建一个新的项目 npm init vitelatest blog-front-admin 中间会弹出询问是否要安装包&#xff0c…

OZON夏季热卖产品有哪些,OZON夏季热卖新品

OZON平台在夏季的热卖产品种类繁多&#xff0c;涵盖了多个领域&#xff0c;主要包括但不限于以下几个方面&#xff0c;接下来看看OZON夏季热卖产品有哪些&#xff0c;OZON夏季热卖新品&#xff01;Top1 运动套装 Костюм спортивный Victorias Secret 商品id…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—透明背景生成工具

大家好&#xff0c;我是设计师阿威 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可以…