【C++】 List 基本使用

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.mzph.cn/diannao/46127.shtml

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

相关文章

课程设计——Python+OpenCV数字图像处理[车牌识别]

Python opencv 车牌识别 数字图像处理课程设计作业Python3OpenCV使用tkinter搭建界面tmp/文件夹是数字图像处理过程chepai/文件夹是车牌图片pic/文件夹是程序界面图PPT文件是验收时要讲的程序是从网上学习的并自己弄的&#xff0c;不完善&#xff0c;识别率不高 开发环境配置…

使用MovaXterm连接VMware的centos

一、确认局域网ip 检查虚拟机分配的网段是否一致 二、确认centos的ip 输入 ip addr 获得设备ip为192.168.153.130 三、用MovaXterm建立ssh连接 有同行可能会问&#xff0c;直接使用VMware操作centos系统不行吗&#xff1f;为什么要再多一步。 理由&#xff1a;1、测试环境c…

【Navicat Premium Lite 17】无需破解、不在担心绿诗涵——官方的免费轻量级Navicat来了

Navicat Premium Lite 是 Navicat 的精简版&#xff0c;它包含了用户执行主要的基本数据库操作所需的核心功能。它允许你同时连接到各种数据库平台&#xff0c;包括 MySQL、PostgreSQL、SQL Server、Oracle、MariaDB&#xff0c;以及 Redis 和 MongoDB 等NoSQL 数据库&#xff…

MVC之 Controller 》》 ModelState ValidationMessageFor ValidationSummary

ModelState是Controller的一个属性&#xff0c;可以被继承自System.Web.Mvc.Controller的那些类访问。它表示在一次POST提交中被提交到服务器的 键值对集合&#xff0c;每个记录到ModelState内的值都有一个错误信息集。尽管ModelState的名字中含有“Model”&#xff0c;但它只有…

JVM监控及诊断工具-命令行篇-jstat命令介绍

JVM监控及诊断工具-命令行篇01-jstat&#xff1a;查看JVM统计信息 一 基本情况二 基本语法2.1 option参数1. 类装载相关的&#xff1a;2. 垃圾回收相关的-gc&#xff1a;显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息…

jmeter-beanshell学习9-放弃beanshell

写这篇时候道心不稳了&#xff0c;前面写了好几篇benashell元件&#xff0c;突然发现应该放弃。想回去改前面的文章&#xff0c;看了看无从下手&#xff0c;反正已经这样了&#xff0c;我淋了雨&#xff0c;那就希望别人也没有伞吧&#xff0c;哈哈哈哈&#xff0c;放在第九篇送…

智慧商超-下

原文&#xff1a;https://blog.c12th.cn/archives/29.html 智慧商超-下 测试&#xff1a;笔记本原装操作系统&#xff1a;Windows 10 家庭中文版 资源分享链接&#xff1a;提取码&#xff1a;uya0 卸载SQL步骤&#xff1a; https://blog.csdn.net/qq1623803207/article/detail…

自定义json序列化和反序列化

一、LocalDateTime反序列化异常 首先我们定义一个java POJO实体类&#xff0c;其中关键的成员变量时birthDate,我们没有采用Date数据类型&#xff0c;而是采用了Java8 新的日期类型LocalDateTime,使用LocalDateTime的好处我就不多说了&#xff0c;有很多的文章解释说明。我们把…

Java常见JUC并发工具类

Lock 并发编程领域的两大核心问题&#xff1a; 一个是 互斥&#xff0c;即同一时刻只允许一个线程访问共享资源 另一个是 同步&#xff0c;即线程之间如何通信、协作 这两大问题&#xff0c;管程&#xff08;synchronized&#xff09;都是能够解决的。Java SDK并发包通过Lock和…

【Linux】进程控制的详细介绍

前言 在此之前&#xff0c;我们学过进程的概念&#xff0c;进程的状态&#xff0c;进程地址空间等一系列进程相关的问题。本章我们继续学习进程&#xff0c;我们要来学习一下进程的控制&#xff0c;关于进程等待&#xff0c;进程替换等问题。 目录 1.再次认识Fork函数1.1 fork…

internet download manager(IDM下载器) 6.42.8.2下载安装使用指南

internet download manager(IDM下载器) 6.42.8.2Z是一款功能强大的下载加速工具&#xff0c;能够显著提升您的下载速度&#xff0c;最高可达500%。它不仅能够加速下载&#xff0c;还能对下载任务进行智能调度&#xff0c;并具备恢复中断下载的能力。根据用户评价&#xff0c;无…

初识C++(命名空间、缺省参数)

初识C 命名空间namespace关键字命名空间的使用 缺省参数 命名空间 namespace关键字 在C中&#xff0c;为了尽可能避免命名冲突&#xff0c;需要对各个变量进行域作用限定&#xff0c;这就需要使用到namespace关键字&#xff0c;namespace可以定义一个命名空间&#xff0c;即命…

LabVIEW红外热波图像缺陷检

开发使用LabVIEW开发的红外热波图像缺陷检测系统。该系统结合红外热像仪、工业相机和高效的数据采集硬件&#xff0c;实现对工件表面缺陷的自动检测和分析。通过LabVIEW的强大功能&#xff0c;系统能够实时采集、处理和显示红外热波图像&#xff0c;有效提高了检测的精度和效率…

vue:标签属性绑定Vue实例【ref,reactive,内置指令v-bind,v-on】,预定义变量、方法【$methods,$computed】

Vue2、3组件通信、双向绑定、插槽slot、内置指令_组件双向绑定-CSDN博客​Vue2&#xff0c;3响应式原理&#xff0c;ref和reactive&#xff0c;toRef和toRefs&#xff0c;shallowRef和shallowRefs_vue2 shallowref-CSDN博客 vue2【Options 选项API、mixin混入】&#xff0c;vu…

WAF基础介绍

WAF 一、WAF是什么&#xff1f;WAF能够做什么 二 waf的部署三、WAF的工作原理 一、WAF是什么&#xff1f; WAF的全称是&#xff08;Web Application Firewall&#xff09;即Web应用防火墙&#xff0c;简称WAF。 国际上公认的一种说法是&#xff1a;Web应用防火墙是通过执行一…

免开steam 脱离steam 进行游戏的小工具

链接&#xff1a;https://pan.baidu.com/s/1k2C8b4jEqKIGLtLZp8YCgA?pwd6666 提取码&#xff1a;6666 我们只需选择游戏根目录 然后输入AppID 点击底部按钮 进行就可以了 关于AppID在&#xff1a;

机器学习——L1 L2 范数 —>L1 L2正则化

1、L1范数和L2范数是机器学习和数据分析中经常使用的两种范数&#xff0c;它们之间存在多个方面的区别。 以下是关于L1范数和L2范数区别的详细解释&#xff1a; 一、定义差异 L1范数&#xff1a;也被称为曼哈顿范数&#xff0c;是向量元素的绝对值之和。对于一个n维向量x&am…

酒店管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;酒店管理员管理&#xff0c;房间类型管理&#xff0c;房间信息管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;房间信息…

Linux介绍与常用命令详解

目录 一、Linux概述 1.Linux发行版 2.Linux目录结构 二、Linux特点 三、Linux用途 四、Linux常用的命令 1.cd指令&#xff08;跳转位置&#xff09; 2.显示目录文件 3.对文件进行操作 4.rm指令&#xff08;删除文件夹指令&#xff09; 5.mv指令 6.查看文件命令 7.进程命令…

【云岚到家】-day05-6-项目迁移-门户-CMS

【云岚到家】-day05-6-项目迁移-门户-CMS 4 项目迁移-门户4.1 迁移目标4.2 能力基础4.2.1 缓存方案设计与应用能力4.2.2 静态化技术应用能力 4.3 需求分析4.3.1 界面原型 4.4 系统设计4.4.1 表设计4.4.2 接口与方案4.4.2.1 首页信息查询接口4.4.3.1 数据缓存方案4.4.3.2 页面静…