C++ STL之 list 基础

news2025/1/21 12:10:47

文章目录

  • 前言
  • STL之list基础知识
    • 1. list的介绍
    • 2. list的使用
      • 2.1 list的构造
      • 2.2 list iterator的使用
      • 2.3 空间相关
      • 2.4 元素访问
      • 2.5 相关函数
      • 2.6 list的迭代器失效
    • 3. list与vector的对比
  • 后记

前言

本篇将学习 list 的基础知识

🕺作者: 迷茫的启明星
专栏:《C++初阶》
😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!

持续更新中~

STL之list基础知识

1. list的介绍

list的文档介绍

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  1. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素
  1. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
  1. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
  1. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问。

    比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;

    list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)

在这里插入图片描述

2. list的使用

2.1 list的构造

构造函数(constructor)接口功能
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)用[first, last)区间中的元素构造list

演示:

void test3()
{
    //构造的list中包含n个值为val的元素
    list<int> l1(10, 6);
    for (auto lt : l1)
    {
        cout << lt;
    }
    cout << endl;

    //拷贝构造函数
    list<int> l2(l1);
    for (auto lt : l2)
    {
        cout << lt;
    }
    cout << endl;

    //构造空的list
    list<int> l3;

    //用[first, last)区间中的元素构造list
    list<int> l4(l1.begin(), l1.end());
    for (auto lt : l2)
    {
        cout << lt;
    }
    cout << endl;
}

输出结果:

在这里插入图片描述

2.2 list iterator的使用

迭代器可以理解成一个指针,该指针指向list中的某个节点

函数声明接口功能
begin + end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin + rend返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置

【注意】

  1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
  2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

演示:

void test4()
{
    //构造的list中包含n个值为val的元素
    list<int> l1;
    for (int i = 0; i < 10; ++i)
    {
        //尾插数据
        l1.push_back(i);
    }
    for (auto lt : l1)
    {
        cout << lt;
    }
    cout << endl << endl;
    //使用l1的数据正向构造,即正向迭代器
    list<int> l2(l1.begin(),l1.end());
    for (auto lt : l2)
    {
        cout << lt;
    }
    cout << endl << endl;
    //使用l1的数据反向构造,即反向迭代器
    list<int> l3(l1.rbegin(), l1.rend());
    for (auto lt : l3)
    {
        cout << lt;
    }
    cout << endl << endl;
}

输出结果:

在这里插入图片描述

2.3 空间相关

函数声明接口说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数

演示:

void test5()
{
    list<int> l1(10, 6);
    //判断l1是否为空,是返回true,否返回false
    cout << l1.empty() << endl;
    //返回l1中有效节点的个数
    cout << l1.size() << endl;
}

输出结果:

在这里插入图片描述

2.4 元素访问

函数声明接口功能
front返回list的第一个节点中值的引用
back返回list的最后一个节点中值的引用

演示:

void test6()
{
    list<int> l1;
    for (int i = 0; i < 10; ++i)
    {
        //尾插数据
        l1.push_back(i);
    }
    for (auto lt : l1)
    {
        cout << lt;
    }
    cout << endl << endl;
    //返回l1的第一个节点的值
    cout << l1.front() << endl;
    //返回l1的最后一个节点的值
    cout << l1.back() << endl;
}

输出结果:

在这里插入图片描述

2.5 相关函数

需要注意的是,这里仅展示常用函数及用法

函数声明接口功能
push_front在list首元素前插入值为val的元素
pop_front删除list中第一个元素
push_back在list尾部插入值为val的元素
pop_back删除list中最后一个元素
insert在list position 位置中插入值为val的元素
erase删除list position位置的元素
swap交换两个list中的元素
clear清空list中的有效元素

演示:

void test7()
{
    list<int> l1(6,1);
    //在l1首元素前插入值为9的元素
    l1.push_front(9);
    l1.push_front(9);

    //删除l1中第一个元素
    l1.pop_front();

    //在l1尾部插入值为8的元素
    l1.push_back(8);

    //删除l1中最后一个元素
    l1.pop_back();

    //在2位置中插入值为7的元素
    auto it = l1.begin();
    it++;
    l1.insert(it,7);

    //删除位置2的元素
    auto it1 = l1.begin();
    it1++;
    l1.erase(it1);
    
    //交换两个list中的元素
    list<int> l2(6, 2);
    swap(l1, l2);
    for (auto lt : l2)
    {
        cout << lt;
    }
    cout << endl << endl;

    for (auto lt : l1)
    {
        cout << lt;
    }
    cout << endl << endl;
}

2.6 list的迭代器失效

我们前面说可以将迭代器理解成指针,迭代器失效就是说迭代器所指的节点无效,即该节点被删除了。因为list的底层结构为带头节点的双向循环链表,因此在list中进行插入是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

举例说:

void test1()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array+sizeof(array)/sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
        l.erase(it);
        ++it;
    }
}

运行情况:

在这里插入图片描述

怎么改正呢?

只需要在下一次使用it的时候先给它赋值

void test2()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array+sizeof(array)/sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        l.erase(it++); // 相当于 it = l.erase(it);
    }
}

3. list与vector的对比

vector与list都是STL中非常重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不同,其主要不同如下:

vectorlist



动态顺序表,一段连续空间带头结点的双向循环链表


访
支持随机访问,访问某个元素效率O(1)不支持随机访问,访问某个元素效率O(N)




任意位置插入和删除效率低,需要搬移元素,时间复杂度为O(N),插入时有可能需要增容,增容:开辟新空间,拷贝元素,释放旧空间,导致效率更低任意位置插入和删除效率高,不需要搬移元素,时间复杂度为O(1)




底层为连续空间,不容易造成内存碎片,空间利用率高,缓存利用率高底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低


原生态指针对原生态指针(节点指针)进行封装




在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来迭代器失效,删除时,当前迭代器需要重新赋值否则会失效插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响
使


需要高效存储,支持随机访问,不关心插入删除效率大量插入和删除操作,不关心随机访问

后记

这篇主要讲述了 list 的基础知识,包括构造方法及相关函数使用等内容。

感谢大家支持!!!

下篇将讲述 list 的模拟实现。

respect!

下篇见!

在这里插入图片描述

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

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

相关文章

网络安全从业人员职业发展和规划

1、为什么做这次分享&#xff1f; 2、人生周期三模型 3、职业生涯阶段划分 4、通用职业发展路径 5、当前安全行业前景如何&#xff1f; 6、安全就业行情如何&#xff1f; 7、安全行业就业市场岗位划分 8、什么是相对比较好的履历&#xff1f; 9、选择甲方还是选择乙方&#xf…

Prompt learning 教学[技巧篇]:通过增加示例、引导词、特殊符号指令等方式让chatgpt输出更好的答案

Prompt learning 教学[技巧篇]&#xff1a;通过增加示例、引导词、特殊符号指令等方式让chatgpt输出更好的答案 技巧1&#xff1a;To Do and Not To Do 在问答场景里&#xff0c;为了让 AI 回答更加准确&#xff0c;一般会在问题里加条件。比如让 AI 推荐一部电影给你 Recomme…

【高数+复变函数】傅里叶变换

文章目录 【高数复变函数】傅里叶变换3 傅里叶变换3.1 基本概念3.2 单位脉冲函数及其傅里叶变换3.3 非周期函数的频谱 上一节 【高数复变函数】傅里叶积分 【高数复变函数】傅里叶变换 3 傅里叶变换 3.1 基本概念 回顾&#xff1a;上一节中的Fourier积分公式 f ( t ) 1 2…

前端二进制流的关系

Blob 全称&#xff1a;binary large object&#xff0c;二进制大对象&#xff0c;是一个js对象&#xff0c;可以用来存储大量二进制编码格式的数据&#xff0c;Blob对象是不可修改的&#xff0c;读取内容的唯一方法是FileReader。 创建一个Blob对象&#xff1a; new Blob(ar…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--后端实现

目录 SSM(Vue3ElementPlusAxiosSSM前后端分离)--后端实现 技术栈 实现功能04-添加家居信息 需求分析/图解 思路分析 代码实现 创建\service\FurnService.java 和\service\FurnServiceImpl.java, 增加添加方法 修改Furn.java , 当创建Furn 对象imgPath 为null 时, imgPa…

Java14-常用类:字符串,日期类,比较器

一&#xff1a;字符串&#xff1a;String 1.概述&#xff1a; String&#xff1a;字符串&#xff0c;使用一对""引起来表示。 1.String 声明 为final的&#xff0c;不可被继承 2.String 实现了Serializable接口&#xff1a;表示字符串是支持序列化的。 实现了Co…

多线程相关高频面试题

一、线程的基础知识 1、线程和进程的区别&#xff1f; 进程是正在运行程序的实例&#xff0c;进程中包含了线程&#xff0c;每个线程执行不同的任务。不同的进程使用不同的内存空间&#xff0c;在当前进程下的所有线程可以共享内存空间。线程更轻量&#xff0c;线程上下文切换…

GPIO口输出与输入模式的理解

问题&#xff1f;看GPIO的结构图&#xff0c;发现&#xff1a; 上拉输入电流是从引脚流入外部 下来输入电流是从引脚流进芯片内部 推挽输出推模式电流是从引脚流入外部 推挽输出挽模式电流是从外部流入内部 输入输出模式都有电流流入流出&#xff0c;为什么还要分为输入输出模…

K8s排错之浏览器打不开K8s Dashboard

一、问题 10.0.0.10 通常会使用加密技术来保护您的信息。Chrome 此次尝试连接到 10.0.0.10 时&#xff0c;该网站发回了异常的错误凭据。这可能是因为有攻击者在试图冒充 10.0.0.10&#xff0c;或者 Wi-Fi 登录屏幕中断了此次连接。请放心&#xff0c;您的信息仍然是安全的&am…

【饿了么UI】elementUI密码框图标实现睁眼和闭眼效果(阿里巴巴iconfront图标库vue项目本地引用)

elementUI中输入框的密码框属性&#xff0c; 默认是一个始终睁眼的图标&#xff0c;测试今天提bug要有闭眼效果&#xff08;无大语&#xff09;… 因为elementUI中的icon没有闭眼的&#xff0c;所以还要去iconfront下载引入 效果图&#xff1a; 点击后 一、下载图标 http…

【LeetCode】138. 复制带随机指针的链表

题目链接&#xff1a;https://leetcode.cn/problems/copy-list-with-random-pointer/description/ &#x1f4d5;题目要求&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。…

基于springboot+mybatis-puls+mysql+html实现大学生创新创业管理系统

基于springbootmybatis-pulsmysqlhtml实现大学生创新创业管理系统 一、系统介绍1、系统主要功能&#xff1a;2.涉及技术框架&#xff1a;3.本项目所用环境&#xff1a; 二、功能展示三、其它系统四、获取源码 一、系统介绍 1、系统主要功能&#xff1a; 学生&#xff1a;申报…

自更新参数web接口预热工具

痛点 日常上线流程中经常需要对接口进行预热&#xff0c;因为服务器每次启动后都有一定次数访问失败&#xff0c;如果不处理将此请求直接抛出&#xff0c;会降低用户体验。当服务器数量较少时&#xff0c;我们可以在发布机器后&#xff0c;待机器启动使用本地hosts更改IP&…

20230510MTCNN3

MTCNN数据制作 - 1 多任务 分类任务 回归任务 模型增加任务&#xff0c;其实就是增加输出 级联即减少了 数据量&#xff0c;又增加了 模型的精度 级联可以让网络变得越快 越好 单独来看这三个网络&#xff0c;它们的效果不会好&#xff0c;因为网络太浅了 但&#xff0c;当…

【嵌入式烧录刷写文件】-1.3-删除/修改Motorola S-record(S19/SREC/mot/SX)文件中指定地址范围内的数据

案例背景&#xff08;共6页精讲&#xff09;&#xff1a; 有如下一段S19文件&#xff0c;如何“自动”地完成地址范围0x9110-0x9113数据的删除或修改。 S0110000486578766965772056312E30352EA6 S123910058595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576775B…

t检验前世今生

1、背景 t检验是科研中非常常用的一种方法和手段&#xff0c;但是理解到位的人并不多&#xff0c;虽然这也不影响其使用。本文主要目的在于将与t检验有关的前前后后都讲明白。 2、补充知识 理解t检验&#xff0c;我们需要补充一些统计学有关的先验知识。 2.1 正态分布 概率…

【文本三剑客】SED

SED 一、sed编辑器1.2sed简介1.3sed工作流程1.4sed命令格式1.5常用选项1.6常用操作 二、sed实验2.1打印内容2.2删除行2.3替换2.4插入 一、sed编辑器 1.2sed简介 sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。sed编辑器可…

链表详解 - C语言描述

目录 认识链表 链表的分类 链表的实现 单链表的增删查改 增操作 删操作 查操作 改操作 带头双向循环链表 认识链表 链表是一种物理存储上非连续&#xff0c;数据元素的逻辑顺序通过链表中的指针链接次序&#xff0c;实现的一种线性存储结构。链表由一系列节点(结点)组…

最火爆ChatGPT知识星球分享,开启与GPT的神奇之旅

今天给大家介绍的是一个讲解ChatGPt的知识星球&#xff0c;这个星球是专门为ChatGPT爱好者和AI绘画感兴趣的朋友们打造的。这个知识星球主题是关于ChatGPT的&#xff0c;旨在提供一个交流、学习和探索GPT的平台。 这里有一个强大的阵容&#xff0c;汇集了许多对人工智能和自然…

.Net平台下OpenGL绘制图形(2)(VS2019,Winform,C#)

本节主要讲诉图形绘制的原理&#xff0c;使用介绍和代码演示。 原理介绍 我们先来讲讲OpenGL的图形绘制。其实&#xff0c;所有的图形都是由许多个小图形连接而成的。你可以理解为是图片的像素&#xff0c;一张彩图是由很多个色彩不一的像素点组合而成。要实现色彩绚丽的图形设…