C++中的List容器用法详解

文章目录

  • C++中的List容器用法详解
  • List 的特点
  • List 的重要接口用法介绍
    • 1.创建和初始化List
      • list
    • 2.插入元素
      • push_back
      • push_fornt
      • insert
    • 删除元素
      • pop_back
      • pop_font
      • clear
      • erase
    • 遍历List
      • 迭代器遍历
      • 范围for遍历
    • 排序List
      • sort
    • 反转List
      • reverse
    • 转移List
      • splice
    • 去重
      • unique
    • 合并
      • merge
    • 总结

C++中的List容器用法详解

在C++标准模板库(STL)中,list 是一种高效的、双向的、动态的容器,它允许在任何位置快速插入和删除元素。list 容器在内部通过节点来存储数据,每个节点都包含数据部分和指向前后节点的指针。这种设计使得 list 在进行插入和删除操作时具有较高的效率,因为只需要修改指针的指向,而不需要移动元素。

List 的特点

std::list 是 C++ 标准模板库(STL)中的一个容器,它具有以下特点:

  1. 双向链表list 是一个双向链表,每个元素都包含一个数据部分和两个指针,分别指向下一个元素和上一个元素。这种结构使得在链表的任何位置插入或删除元素都非常高效。

  2. 动态大小list 容器的大小是动态的,可以随着元素的添加和删除而自动调整。它不需要预先分配固定大小的内存。

  3. 不连续内存分配:与数组或 std::vector 不同,list 的元素不存储在连续的内存块中。每个元素都是独立分配的,这使得 list 在处理大量数据时能够提供更好的内存利用率和性能。

  4. 高效插入和删除:由于其链表结构,list 在任何位置插入或删除元素的时间复杂度都是常数时间(O(1)),这比 std::vector 在中间位置插入或删除元素的线性时间(O(n))要快得多。

  5. 不支持随机访问:由于 list 是一个链表,它不支持像数组或 std::vector 那样的随机访问。访问 list 中的元素需要从头开始遍历,因此其时间复杂度为线性时间(O(n))。

  6. 迭代器支持list 提供了双向迭代器,这意味着可以从两个方向遍历 list,但不支持随机访问迭代器。

  7. 内存管理list 的内存管理是自动的,当元素被插入时,list 会自动分配内存;当元素被删除时,list 会自动释放内存。

  8. 不支持直接访问:不能通过索引直接访问 list 中的元素,必须使用迭代器。

  9. 不支持 at() 方法list 不提供 at() 方法来访问元素,因为这需要随机访问能力,而 list 不支持随机访问。

  10. 不支持 [] 运算符:与 at() 方法类似,list 也不支持 [] 运算符来访问元素,原因同上。

  11. 不支持 resize() 方法list 不提供 resize() 方法来改变容器的大小,因为 list 的大小是动态的,且不连续分配内存。

  12. 不支持 reserve() 方法list 不提供 reserve() 方法来预分配内存,因为 list 的内存分配策略是自动的。

list 的这些特点使得它在需要频繁插入和删除操作的场景中非常有用,但在需要快速随机访问的场景中则不如 std::vector 或数组高效。

List 的重要接口用法介绍

1.创建和初始化List

在C++中,可以使用多种方式创建和初始化 list 容器:
在这里插入图片描述

list

  • (1)
    空容器构造函数(默认构造函数)构造一个没有元素的空容器。
  • (2)
    构造一个包含n个元素的容器。每个元素都初始化为val。
  • (3)
    构造一个包含与[first,last)范围相同数量元素的容器,每个元素以相同的顺序从该范围内的相应元素构造。
  • (4)
    构造了一个包含 x 中每个元素副本的容器,元素顺序与 x 中的顺序相同。
#include <iostream>
#include <list>int main() {// (1)创建一个空的liststd::list<int> mylist;// (2)创建一个有n个空间每个空间都存val的liststd::list<int> mylist2(5,10);// 使用初始化列表创建liststd::list<int> mylist3 = {1, 2, 3, 4, 5};// (3)创建一个包含一些整数的数组int arr[] = { 10, 20, 30, 40, 50 };// 创建一个指向数组的迭代器范围int* first = arr;int* last = arr + sizeof(arr) / sizeof(arr[0]);// 使用迭代器范围创建一个liststd::list<int> mylist3(first, last);// (4)使用另一个list初始化std::list<int> mylist4(mylist2);return 0;
}

2.插入元素

在这里插入图片描述

push_back

  • list 容器的末尾添加了一个新元素,位于其当前的最后一个元素之后。val 的内容被复制(或移动)到新元素中,就是尾插个节点
	std::list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);

在这里插入图片描述

push_fornt

  • 就是头插个节点
    std::list<int> lt;lt.push_front(1);lt.push_front(2);lt.push_front(3);

在这里插入图片描述

insert

  • (1)
    就是指定位置的元素之前进行插入新元素
  • (2)
    选择插入位置进行单个或者多个元素的插入
  • (3)
    进行[first,last)范围的插入
	std::list<int> mylist1 = { 1, 2, 3, 4, 5 }; // 初始化列表std::list<int>::iterator it1 = mylist1.begin(); // 获取迭代器// 在迭代器 it 指向的位置之前插入值为 10 的元素it1 = mylist1.insert(it1, 10);//(1)std::list<int> mylist2 = { 1, 2, 3, 4, 5 }; // 初始化列表std::list<int>::iterator it2 = mylist2.begin(); // 获取迭代器// 在迭代器 it 指向的位置之前插入 2 个值为 10 的元素mylist2.insert(it2, 2, 10);//(2)std::list<int> mylist3 = { 1, 2, 3, 4, 5 }; // 初始化列表std::vector<int> myvector = { 6, 7, 8 }; // 初始化向量std::list<int>::iterator it3 = mylist3.begin(); // 获取迭代器// 在迭代器 it 指向的位置之前插入 myvector 中的元素mylist3.insert(it3, myvector.begin(), myvector.end());//(3)

删除元素

在这里插入图片描述

pop_back

  • 删除末尾元素

在这里插入图片描述


pop_font

  • 删除开头元素

在这里插入图片描述


clear

  • 清空整个list
mylist.pop_back(); 
mylist.pop_front(); 
mylist.clear();  

在这里插入图片描述

erase

  • (1)
    接受一个迭代器 position ,它指向你想要删除的单个元素。这个元素会被从容器中移除,容器的大小会减一。返回值是一个迭代器,指向被删除元素之后的元素,如果 position 是容器中的最后一个元素,则返回 end() 。
  • (2)
    接受一对迭代器 first 和 last ,它们定义了一个范围。这个范围内的所有元素都会被从容器中移除。返回值是一个迭代器,指向被删除范围之后的第一个元素,如果 last 是容器中的最后一个元素,则返回 end() 。
	std::list<int> mylist1 = { 1, 2, 3, 4, 5 };std::list<int>::iterator it = mylist1.begin();// 删除迭代器 it 指向的元素it = mylist1.erase(it);//(1)std::list<int> mylist2 = { 1, 2, 3, 4, 5 };std::list<int>::iterator it1 = mylist2.begin();std::list<int>::iterator it2 = mylist2.begin();std::advance(it2, 3); // 移动 it2 到第四个元素// 删除从 it1 到 it2 范围内的元素it1 = mylist2.erase(it1, it2);//(2)

遍历List

迭代器遍历

for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it) {std::cout << *it << " ";
}

范围for遍历

	list<int> lt = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };for (auto e : lt){cout << e << " ";}cout << endl;

排序List

在这里插入图片描述

sort

  • (1)
    升序排序
  • (2)
    降序排序(得需要仿函数)
	list<int> lt = { 1, 3, 2, 5, 4, 9, 8, 7, 6 };//排序升序lt.sort();lt.sort(greater<int>());//降序,greater<int>()//仿函数

反转List

在这里插入图片描述

reverse

  • 反转或者说逆置list
mylist.reverse(); // 反转list中的元素顺序

转移List

在这里插入图片描述

splice

  • 注意:
    转移之后lt3直接转移走,lt3里面什么都没有了就
  • 吐槽:
    虽说起名字叫splice但是还是感觉transfers更贴近一点
	//splice (transfers) 转移list<int> lt2;lt2.push_back(1);lt2.push_back(3);lt2.push_back(5);lt2.push_back(4);lt2.push_back(2);for (auto e : lt2){cout << e << " ";}cout << endl;lt2.splice(lt2.end(), lt2, lt2.begin());for (auto e : lt2){cout << e << " ";}cout << endl;list<int> lt3;lt3.push_back(1);lt3.push_back(2);lt3.push_back(3);for (auto e : lt3){cout << e << " ";}cout << endl;lt2.splice(lt2.end(), lt3);for (auto e : lt2){cout << e << " ";}cout << endl;//转移之后lt3直接转移走,lt3里面什么都没有了就for (auto e : lt3){cout << e << " ";}cout << endl;

去重

在这里插入图片描述

unique

  • (1)
    去除list中重复的元素
  • (2)
    接受一个二元谓词( BinaryPredicate ),用于定义两个元素是否相等。默认情况下,如果两个元素相等(即它们的值相同),则认为它们是重复的。unique 函数会遍历列表,并移除所有相邻的重复元素,只保留第一个元素。新列表的大小会减小,但元素的顺序不会改变。
  • 注意:
    在用去重函数之前一定要进行排序
	//去重 unique(得先排序)lt.unique();//(1)//(2)#include <iostream>#include <list>#include <algorithm> // for std::equal_tobool is_equal(const int& a, const int& b) {return a == b;}int main() {std::list<int> mylist = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};// 使用自定义的二元谓词来定义相等性mylist.unique(is_equal);// 打印列表以查看结果for (int& elem : mylist) {std::cout << elem << " ";}std::cout << std::endl;return 0;
}

合并

在这里插入图片描述

merge

  • 用于合并两个有序序列。 std::merge 函数定义在 头文件中,它接受两个有序序列的迭代器范围,并将它们合并成一个有序序列。
#include <iostream>
#include <list>
#include <algorithm> // for std::merge
#include <iterator>   // for std::ostream_iteratorint main() {std::list<int> list1 = {1, 3, 5, 7};std::list<int> list2 = {2, 4, 6, 8};std::list<int> merged_list;// 使用 std::merge 合并两个有序列表std::merge(list1.begin(), list1.end(),list2.begin(), list2.end(),std::back_inserter(merged_list));// 打印合并后的列表std::copy(merged_list.begin(), merged_list.end(),std::ostream_iterator<int>(std::cout, " "));std::cout << std::endl;return 0;
}

总结

list 是C++标准模板库中非常强大的容器之一,它提供了快速的插入和删除操作,并且支持双向迭代。通过本文的介绍,你应该对 list 的基本用法有了一个大致的了解。在实际编程中,根据具体需求选择合适的容器是非常重要的,list 适合于那些需要频繁插入和删除元素的场景。

希望这篇文章能够帮助你更好地理解和使用C++中的 list 容器。如果你有任何问题或需要进一步的解释,请随时在评论区留言。

小卷王们,用你们勤劳的小手给我点点赞,蟹蟹

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

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

相关文章

网站可扩展架构设计——中台

从公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- 一、中台简介 1.传统项目架构的痛点 (1)重复造轮子 各项目相对独立&#xff0c;许多项目在重复造轮子&#xff0c;让项目本身越来越臃肿&#xf…

[Leetcode笔记] 动态规划相关

前言 写题目写到了一些和动态规划相关的内容&#xff0c;所以在这里记录一下 LCR 089 题解思路 总的来说&#xff0c;就是用一个数组去存储当前的最优解&#xff0c;然后从0开始一路向上顺推过去&#xff0c;求得最后一位的最优解。 class Solution { public:int rob(vect…

检测头篇 | 利用RT-DETR模型的检测头去替换YOLOv8中的检测头

前言:Hello大家好,我是小哥谈。RT-DETR号称是打败YOLO的检测模型,其作为一种基于Transformer的检测方法,相较于传统的基于卷积的检测方法,提供了更为全面和深入的特征理解,将RT-DETR检测头融入YOLOv8,我们可以结合YOLO的实时检测能力和RT-DETR的深度特征理解能力,打造出…

VLAN基础讲解+不同VLAN间通信(实验)

第一章 VLAN基础 1.1 什么是VLAN 随着网络中计算机的数量越来越多&#xff0c;传统的以太网络开始面临广播泛滥以及安全性无法保证等各种问题。 VLAN即虚拟局域网&#xff0c;是将一个物理的局域网在逻辑上划分成多个广播域的技术。通过在交换机上配置VLAN&a…

基于深度学习的吸烟检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;本文深入研究了基于YOLOv8/v7/v6/v5等深度学习模型的吸烟行为检测系统&#xff0c;核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;进行性能指标对比&#xff1b;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码&#xff0c;及…

从0配置React

在本地安装和配置React项目&#xff0c;您可以使用create-react-app这个官方推荐的脚手架工具。以下是安装React的步骤&#xff0c;包括安装Node.js、使用create-react-app创建React应用&#xff0c;以及启动开发服务器。 下载安装node.js运行以下命令&#xff0c;验证Node.js…

【Qt 学习笔记】Qt 开发环境的搭建 | Qt 安装教程

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt 开发环境的搭建 | Qt 安装教程 文章编号&#xff1a;Qt 学习笔记 /…

外贸建站:WordPress搭建外贸独立站零基础自建站完整教程(2024)

对于做外贸来说&#xff0c;拥有自己的外贸独立网站真的非常重要。在外贸领域&#xff0c;如今各平台竞争激烈&#xff0c;规则多&#xff0c;成本高&#xff0c;价格战、政策变化快&#xff0c;还存在封店风险等等因素。在这种情况下&#xff0c;拥有外贸独立站就能很好规避上…

攻防世界[EASYHOOK]

阅读须知&#xff1a; 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者 本人负责&#xff0c;作者不为此承担任何责任,如…

STM32学习和实践笔记(4): 分析和理解GPIO_InitTypeDef GPIO_InitStructure (b)

继续上篇博文&#xff1a;STM32学习和实践笔记&#xff08;4&#xff09;: 分析和理解GPIO_InitTypeDef GPIO_InitStructure (a)-CSDN博客 往下写&#xff0c; 为什么&#xff1a;当GPIO_InitStructure.GPIO_PinGPIO_Pin_0 ; 时&#xff0c;其实就是将对应的该引脚的寄存器地…

Xxxxxx

数据库 1&#xff0c;B树与B树区别 1&#xff0c;B树每个节点存ID与其他数据字段&#xff0c;B非叶子结点&#xff0c;只存ID&#xff0c;叶子结点存完整数据 好处&#xff1a;每个层级B树&#xff0c;可以存储更多的额数据&#xff0c;层级更少&#xff0c;更扁平&#xff…

【语义分割实战(1)】U-Net语义分割:训练自己的数据集

一、U-Net图像语义分割原理 UNet最早发表在2015的MICCAI会议上&#xff0c;4年多的时间&#xff0c;论文引用量已经达到了9700多次。 UNet成为了大多做医疗影像语义分割任务的baseline&#xff0c;同时也启发了大量研究者对于U型网络结构的研究&#xff0c;发表了一批基于UNet…

Java中线程详解

文章目录 相关概念多线程概念实现方式继承Thread类实现Runnable接口比较 常用方法线程安全产生的原因解决思想同步同步代码块同步方法Lock锁机制 死锁概念避免 状态线程间的通讯介绍方法 相关概念 并行&#xff1a;在同一时刻&#xff0c;有多个任务在多个CPU上同时执行并发&a…

抖店新手从0-1起店教程:新手开抖店别乱操作!这才是正确流程!

哈喽~我是电商月月 新手开抖店为什么不好成功&#xff0c;那是因为你没接触过电商&#xff0c;不懂其中的步骤&#xff0c;一些细节没处理好&#xff0c;开店就已经注定失败&#xff01; 废话不多说&#xff0c;直接入正题 一&#xff0e;开店&#xff0c;入驻抖店 1&#…

韩顺平 | 零基础快速学Python

环境准备 开发工具&#xff1a;IDLE、Pycharm、Sublime Text、Eric 、文本编辑器&#xff08;记事本/editplus/notepad&#xff09; Python特点&#xff1a;既支持面向过程OOP、也支持面向对象编程&#xff1b;具有解释性&#xff0c;不需要编程二进制代码&#xff0c;可以直…

算法沉淀——动态规划篇(子数组系列问题(上))

算法沉淀——动态规划篇&#xff08;子数组系列问题&#xff08;上&#xff09;&#xff09; 前言一、最大子数组和二、环形子数组的最大和三、乘积最大子数组四、乘积为正数的最长子数组长度 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都…

基于SSM+Jsp+Mysql的航空机票预订系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

小红数组操作(结构体模拟链表详细解析)(双向链表)c/c++

题目描述: 小红拿到了一个数组&#xff0c;初始数组为空&#xff0c;她希望你实现以下两种操作&#xff1a; 1. 输入x,y&#xff0c;将x插入在元素y的右边。保证此时数组中没有元素等于x&#xff0c;且数组中存在一个y。特殊的&#xff0c;如果将x插入在数组的最左边&#xff0…

hadoop在linux上启动成功了,但是浏览器访问不了

根据网上的资料进行安装hadoop的伪集群 都安装成功&#xff0c;并且启动也成功了&#xff0c;如下图所示&#xff1a; 2、但是在浏览器上确是怎么也访问不了&#xff0c; 解决思路&#xff0c; 2.1、根据网上的一些文章处理解决是关闭防火墙&#xff0c; 2.1.1、我根据操作步骤…

影视剪辑来这6个网站找视频素材~

影视剪辑&#xff0c;一般都是先找影视资源&#xff0c;保存百度云下载或者直接录屏&#xff0c;再进行二次创作&#xff0c;找影视资源可以到下面这个网站&#xff0c;绝对能找到90%的电视剧、电影。 茶杯狐 一个影视资源搜索网站&#xff0c;页面非常干净&#xff0c;提供了各…