当前位置: 首页 > news >正文

【C++】list的使用(上)

在这里插入图片描述

🔥个人主页: Forcible Bug Maker
🔥专栏: STL || C++

目录

  • 前言
  • 🌈关于list
  • 🔥默认成员函数
    • ==构造函数(constructor)==
    • ==析构函数(destructor)==
    • ==赋值运算符重载==
  • 🔥迭代器接口(Iterators)
  • 🔥容量获取接口(Capacity)
    • ==empty和size==
  • 🔥元素获取(Element access)
  • 🔥修改器(Modifiers)
    • ==assign==
    • ==push_back,pop_back,push_front和pop_front==
    • ==insert==
    • ==erase==
    • ==resize==
    • ==clear==
  • 结语

前言

本篇博客主要内容:STL库中list的介绍以及list用法的讲解

我们已经知道,stringvector的底层都是简单的顺序表,而list的底层就和之前的两个大不相同了,list的底层是一个带头双向循环链表。学习list之前,如果你还不知道什么是链表,完全由必要学习一下,可以看看我初阶数据结构所讲到的内容:初阶数据结构-顺序表和链表(C语言)

在C++中,我们可以直接使用list创建链表。

🌈关于list

在这里插入图片描述
list是可以在常数范围内任意位置进行插入和删除的序列式容器,并且可以前后双向迭代。

list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针向其前一个元素和后一个元素。

list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已经让其更简单更高效。

与其他序列式容器相比(array,vector,deque),list通常在任意位置进行插入,移除元素的执行效率更好。

于其他序列式容器相比,list和forward_list最大的缺陷是不支持元素的随机访问,比如:需要访问list的第六个元素,必须从已有的位置(比如头部或尾部)迭代到该位置,这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个结点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)。

🔥默认成员函数

在这里插入图片描述

构造函数(constructor)

在这里插入图片描述

注:对于最后一个参数(alloc),可以不用深究,在后期学了内存池相关的内容后会细讲。

构造一个list容器对象,可以根据以下四种方式初始化:
default (1)

explicit list (const allocator_type& alloc = allocator_type());

这是std::list无参构造。它创建了一个不含任何元素的空list对象。其中explicit关键字阻止了隐式类型转换。

fill (2)

explicit list (size_type n, const value_type& val = value_type(),const allocator_type& alloc = allocator_type());

构造一个含有n个val值得list对象

range (3)

template <class InputIterator>list (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type());

按迭代器区间[first, last) 的内容顺序构造list对象

copy (4)

list (const list& x);

构造一个x对象得拷贝
允许隐式类型转换。

代码案例:

// constructing lists
#include <iostream>
#include <list>int main()
{// constructors used in the same order as described above:std::list<int> first;                                // 构建数据类型为整型的一个空链表std::list<int> second(4, 100);                       // 构建一个包含四个值为100的链表std::list<int> third(second.begin(), second.end());  // 通过second链表的迭代器构建thirdstd::list<int> fourth(third);                       // 用third拷贝一个相同的链表fourth// the iterator constructor can also be used to construct from arrays:int myints[] = { 16,2,77,29 };std::list<int> fifth(myints, myints + sizeof(myints) / sizeof(int));std::cout << "The contents of fifth are: ";for (std::list<int>::iterator it = fifth.begin(); it != fifth.end(); it++)std::cout << *it << ' ';std::cout << '\n';return 0;
}

在这里插入图片描述

析构函数(destructor)

在这里插入图片描述
析构函数是当编译器出了对象的生命周期时自动调用的默认成员函数,释放开辟的内存空间

赋值运算符重载

在这里插入图片描述

通过已有对象给被操作对象分配新的值,覆盖它原来的内容,并根据内容调整size的大小。

 list& operator= (const list& x);

从x中拷贝所有的内容到被操作list对象中
在调用之前容器中持有的任何元素都将被分配给新值或被销毁。

代码案例:

// assignment operator with lists
#include <iostream>
#include <list>int main()
{std::list<int> first(3);      // list of 3 zero-initialized intsstd::list<int> second(5);     // list of 5 zero-initialized intssecond = first;first = std::list<int>();std::cout << "Size of first: " << int(first.size()) << '\n';std::cout << "Size of second: " << int(second.size()) << '\n';return 0;
}

两个包含整型元素的列表容器都被初始化为不同大小的序列。然后,second容器被first容器赋值,所以现在两个容器相等并且大小都是3。接着,first容器被赋值给一个新构造的空容器对象(匿名对象),因此它的大小最终变为0。
在这里插入图片描述

🔥迭代器接口(Iterators)

在这里插入图片描述
对于STL的各种容器,迭代器的规则都是极其相似的。

和vector和string相同,begin获取指向list对象首元素的迭代器,end指向链表尾元素下一位的迭代器。

我认为迭代器在vector和string的基础上可以直接上代码了,大家能直接了解其用法。

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt({ 1,2,3,4 });// 获取正向迭代器遍历list<int>::iterator it = lt.begin();while (it != lt.end()) {cout << *it << " ";++it;}cout << endl;// 获取反向迭代器遍历list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()) {cout << *rit << " ";++rit;}cout << endl;return 0;
}

在这里插入图片描述
不过在使用list迭代器需要特别注意的一点:list链表的迭代器不支持加减运算,只支持++和- -运算符,如it += 1it = it + 3的写法会使编译器报错。

🔥容量获取接口(Capacity)

在这里插入图片描述

empty和size

bool empty() const;

判断list对象是否为空

size_type size() const;

获取list对象元素个数

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt1;list<int> lt2({ 1,2,3,4 });cout << "lt1.empty():" << lt1.empty() << endl;cout << "lt2.empty():" << lt2.empty() << endl;cout << endl;cout << "lt1.size():" << lt1.size() << endl;cout << "lt2.size():" << lt2.size() << endl;return 0;
}

在这里插入图片描述

🔥元素获取(Element access)

在这里插入图片描述

  reference front();
const_reference front() const;

获取list对象首元素

reference back();
const_reference back() const;

获取list对象尾元素

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt({ 1,2,3,4 });cout << lt.front() << endl;cout << lt.back() << endl;return 0;
}

在这里插入图片描述

🔥修改器(Modifiers)

在这里插入图片描述

assign

在这里插入图片描述
range (1)

template <class InputIterator>void assign (InputIterator first, InputIterator last);

fill (2)

void assign (size_type n, const value_type& val);

两个重载都可以给list对象分配新内容,将对象原有的内容覆盖。

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt1({ 1,2,3,4 });list<int> lt2({ 0,0,0,0 });lt1.assign(lt2.begin(), lt2.end());for (auto e : lt1) {cout << e << " ";}cout << endl;lt1.assign(8, -1);for (auto e : lt1) {cout << e << " ";}return 0;
}

在这里插入图片描述

push_back,pop_back,push_front和pop_front

分别对应着链表的尾插尾删和头插头删

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt({ 0,0,0 });for (auto e : lt) {cout << e << " ";}cout << endl;lt.push_back(-1);for (auto e : lt) { cout << e << " "; }cout << endl;lt.pop_back();for (auto e : lt) { cout << e << " "; }cout << endl;lt.push_front(-1);for (auto e : lt) { cout << e << " "; }cout << endl;lt.pop_front();for (auto e : lt) { cout << e << " "; }cout << endl;return 0;
}

在这里插入图片描述

insert

在这里插入图片描述
single element (1)

iterator insert (iterator position, const value_type& val);

在迭代器指向元素之前插入val。
fill (2)

void insert (iterator position, size_type n, const value_type& val);

在迭代器指向元素之前插入n个val。
range (3)

template <class InputIterator>void insert (iterator position, InputIterator first, InputIterator last);

在迭代器指向元素之前按顺序插入迭代器区间[first, last)内的值。

带吗案例:

#include <iostream>
#include <list>
#include <vector>int main()
{std::list<int> mylist;std::list<int>::iterator it;// set some initial values:for (int i = 1; i <= 5; ++i) mylist.push_back(i); // 1 2 3 4 5it = mylist.begin();++it;       // it points now to number 2           ^mylist.insert(it, 10);                        // 1 10 2 3 4 5// "it" still points to number 2                      ^mylist.insert(it, 2, 20);                      // 1 10 20 20 2 3 4 5--it;       // it points now to the second 20            ^std::vector<int> myvector(2, 30);mylist.insert(it, myvector.begin(), myvector.end());// 1 10 20 30 30 20 2 3 4 5//               ^std::cout << "mylist contains:";for (it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在这里插入图片描述

erase

在这里插入图片描述

iterator erase (iterator position);
iterator erase (iterator first, iterator last);

删除list容器中一个迭代器(position)指向的元素或者一段迭代器区间(first, last]内的元素
返回值为指向被删除元素下一元素的迭代器

代码案例:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt({ 1,2,3,4,5 });for (auto e : lt) { cout << e << " "; }cout << endl;list<int>::iterator it = lt.begin();++it;it = lt.erase(it);for (auto e : lt) { cout << e << " "; }cout << endl;it = lt.erase(it, lt.end());for (auto e : lt) { cout << e << " "; }cout << endl;return 0;
}

在这里插入图片描述

resize

void resize (size_type n, value_type val = value_type());

此接口函数用于调整容器的大小,使其包含n个元素。
如果n小于当前容器的大小,内容将被缩减为其前n个元素,移除超出n的部分(并销毁它们)。
如果n大于当前容器的大小,内容将通过在末尾插入所需数量的新元素来扩展,以达到大小为n。如果指定了val,新元素将被初始化为val的副本;否则,它们将进行默认值初始化。

// resizing list
#include <iostream>
#include <list>int main()
{std::list<int> mylist;// set some initial content:for (int i = 1; i < 10; ++i) mylist.push_back(i);mylist.resize(5);mylist.resize(8, 100);mylist.resize(12);std::cout << "mylist contains:";for (std::list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在这里插入图片描述

clear

void clear();

从列表容器(其中的元素将被销毁)中移除所有元素,使size的大小变为0

结语

本篇博客给大家初步介绍了list,其底层是一个双向循环链表,讲解了list的一些函数接口,如修改器,元素访问,以及迭代器接口的使用方式。这些功能和规则和vector,string的接口大同小异,名称也大都一致,降低了我们的学习成本。
博主后续还会产出更多有关于STL的内容,感谢大家的支持。♥

相关文章:

【C++】list的使用(上)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f308;关于list&#x1f525;默认成员函数构造函数&#xff08;constructor&#xff09;析构函数&#xff08;destructor&#xff09;赋值运算符重载 &#x1…...

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452 需强化知识点 python list sort的高阶用法&#xff0c;两个key&#xff0c;另一种逆序写法python list insert的用法 题目 860. 柠檬水找零 思路&#xff1a;注意 20 块找零&#xff0c;可以找3张5块升…...

concat是什么?前端开发者必须掌握的数组拼接利器

concat是什么&#xff1f;前端开发者必须掌握的数组拼接利器 在前端开发中&#xff0c;concat是一个极其重要的概念&#xff0c;它能够帮助我们实现数组之间的无缝拼接。那么&#xff0c;concat到底是什么&#xff1f;为什么它在前端开发中如此重要&#xff1f;接下来&#xf…...

WHAT - 容器化系列(一)

这里写目录标题 一、什么是容器与虚拟机1.1 什么是容器1.2 容器的特点1.3 容器和虚拟机的区别虚拟机&#xff08;VM&#xff09;&#xff1a;基于硬件的资源隔离技术容器&#xff1a;基于操作系统的资源隔离技术对比总结应用场景 二、容器的实现原理1. Namespace&#xff08;命…...

QT7_视频知识点笔记_67_项目练习(页面以及对话框的切换,自定义数据类型,DB数据库类的自定义及使用)

视频项目&#xff1a;7----汽车销售管理系统&#xff08;登录&#xff0c;品牌车管理&#xff0c;新车入库&#xff0c;销售统计图表&#xff09;-----项目视频没有&#xff0c;代码也不全&#xff0c;更改项目练习&#xff1a;学生信息管理系统。 学生信息管理系统&#xff1…...

windows10系统64位安装delphiXE11.2完整教程

windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容&#xff1a;windows10…...

09.责任链模式

09. 责任链模式 什么是责任链设计模式&#xff1f; 责任链设计模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求沿着处理者对象组成的链进行传递&#xff0c;直到有一个处理者对象能够处理该请求为止。这种模式的目的…...

Amazon云计算AWS(一)

目录 一、基础存储架构Dynamo&#xff08;一&#xff09;Dynamo概况&#xff08;二&#xff09;Dynamo架构的主要技术 二、弹性计算云EC2&#xff08;一&#xff09;EC2的基本架构&#xff08;二&#xff09;EC2的关键技术&#xff08;三&#xff09;EC2的安全及容错机制 提供的…...

十_信号4-SIGCHLD信号

SIGCHLD信号 在学习进程控制的时候&#xff0c;使用wait和waitpid系统调用何以回收僵尸进程&#xff0c;父进程可以阻塞等待&#xff0c;也可以非阻塞等待&#xff0c;采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待&#xff0c;父进程就被阻塞了&#xff0c;什么都干…...

HCIP的学习(27)

RSTP—802.1W—快速生成树协议 STP缺陷&#xff1a; 1、收敛速度慢----STP的算法是一种被动的算法&#xff0c;依赖于计时器来进行状态变化 2、链路利用率低​ RSTP向下兼容STP协议。&#xff08;STP不兼容RSTP&#xff09; 改进点1—端口角色 802.1D协议---根端口、指定端口…...

6. MySQL 查询、去重、别名

文章目录 【 1. 数据表查询 SELECT 】1.1 查询表中所有字段使用 * 查询表的所有字段列出表的所有字段 1.2 查询表中指定的字段 【 2. 去重 DISTINCT 】【 3. 设置别名 AS 】3.1 为表指定别名3.2 为字段指定别名 【 5. 限制查询结果的条数 LIMIT 】5.1 指定初始位置5.2 不指定初…...

Oracle导出clob字段到csv

使用UTL_FILE ref: How to Export The Table with a CLOB Column Into a CSV File using UTL_FILE ?(Doc ID 1967617.1) --preapre data CREATE TABLE TESTCLOB(ID NUMBER, MYCLOB1 CLOB, MYCLOB2 CLOB ); INSERT INTO TESTCLOB(ID,MYCLOB1,MYCLOB2) VALUES(1,Sample row 11…...

C++无锁(lock free)队列moodycamel::ConcurrentQueue

moodycamel::ConcurrentQueue介绍 moodycamel::ConcurrentQueue一个用C++11实现的多生产者、多消费者无锁队列。 它具有以下特点: 1.快的让人大吃一惊,详见不同无锁队列之间的压测对比 2.单头文件实现,很容易集成到你的项目中 3.完全线程安全的无锁队列,支持任意线程数的并…...

python办公自动化——(二)替换PPT文档中图形数据-柱图

效果: 数据替换前 &#xff1a; 替换数据后&#xff1a; 实现代码 import collections.abc from pptx import Presentation from pptx.util import Cm,Pt import pyodbc import pandas as pd from pptx.chart.data impo…...

vue不同页面切换的方式(Vue动态组件)

v-if实现 <!--Calender.vue--> <template><a-calendar v-model:value"value" panelChange"onPanelChange" /></template> <script setup> import { ref } from vue; const value ref(); const onPanelChange (value, mod…...

Linux下Qt Creator无法输入中文(已解决)

1. 首先确保安装了搜狗输入法&#xff0c;且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本&#xff0c;如下图所示&#xff0c;为基于Qt6的。 4. 进入源码目录&#xff0c;建立build文件夹&#xff0c;修改CMak…...

Codeforces 提交Java代码(自己处理输入输出)

示例一&#xff08;A. Watermelon&#xff09; 题目地址 Problem - 4A - Codeforces 题目截图 提交方式 可以提交本地文件&#xff0c;也可以在线提交。我们这里选择在线提交方式&#xff0c;点击上图中的 SUBMIT 按钮&#xff0c;会进入如下界面。 输入Java代码效果如下&a…...

剖析vue中nextTick源码

代码逻辑梳理&#xff1a; callbacks 数组用于存储待执行的回调函数&#xff0c;waiting 变量用于标记是否有待执行的回调函数。 flushCallbacks 函数用于执行所有存储在 callbacks 数组中的回调函数&#xff0c;并在执行完成后将 waiting 设置为 false。 timer 函数根据环境…...

SSM牙科诊所管理系统-计算机毕业设计源码98077

目 录 摘要 1 绪论 1.1研究目的与意义 1.2国内外研究现状 1.3ssm框架介绍 1.4论文结构与章节安排 2 牙科诊所管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能…...

【C++进阶】深入STL之string:模拟实现走进C++字符串的世界

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C模板入门 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀STL之string &#x1f4d2;1. string…...

go语言linux安装

下载&#xff1a;https://go.dev/dl/ 命令行使用 wget https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz解压下载的压缩包&#xff0c;linux建议放在/opt目录下 我放在/home/ihan/go_sdk下 sudo tar -C /home/ihan/go_sdk -xzf go1.19.3.linux-amd64.tar.gz 这里的参数…...

vi和vim有什么不同?

vi 和 vim 都是流行的文本编辑器&#xff0c;它们之间有以下主要区别&#xff1a; 历史&#xff1a; vi 是一个非常古老的文本编辑器&#xff0c;最初由 Bill Joy 在 1976 年为 Unix 系统编写。vim&#xff08;Vi IMproved&#xff09;是 vi 的一个增强版&#xff0c;由 Bram M…...

CSS动画效果(鼠标滑过按钮动画)

1.整体效果 https://mmbiz.qpic.cn/sz_mmbiz_gif/EGZdlrTDJa5SXiaicFfsrcric7TJmGO6YddqC4wFPdM7PGzPHuFgvtDS7MIvnLHB4WFaKia0Qh8VCyUaoyHMc2Zltg/640?wx_fmtgif&fromappmsg&tpwebp&wxfrom5&wx_lazy1&wx_co1 网页设计中的按钮不仅是用户交互的桥梁&#…...

数据结构(C):从初识堆到堆排序的实现

目录 &#x1f31e;0.前言 &#x1f688; 1.堆的概念 &#x1f688; 2.堆的实现 &#x1f69d;2.1堆向下调整算法 &#x1f69d;2.2堆的创建&#xff08;堆向下调整算法&#xff09; ✈️2.2.1 向下调整建堆时间复杂度 &#x1f69d;2.3堆向上调整算法 &#x1f69d;2.…...

ChatGLM3-6B部署

ZhipuAI/chatglm3-6b 模型文件地址 chatglm3-6B-32k-int4 量化的模型地址 ChatGLM3 代码仓库 ChatGLM3 技术文档 cpolar http xxx 端口 /anaconda3/envs/chatglm2/lib/python3.8/site-packages/gradio$ networking.py 硬件环境 最低要求&#xff1a; 为…...

代码随想录35期Day54-JavaScript

Day54题目 ### LeetCode739每日温度 核心思想:今天主要是学会单调栈的使用.找到比元素更大的下一个元素,如果比栈顶元素小就入栈,否则就出栈顶元素,当前元素就是比栈顶元素大的"下一个更大的元素". /*** param {number[]} temperatures* return {number[]}*/ var …...

把自己的服务器添加到presearch节点

Presearch is a scam. Before, judging by the price of the token you should have been able to get between $150-$200 after 12-13 months of regular searches. "If you use this service for the next 11 years you will have earned $30!" Presearch大约需要…...

Open3D(C++) OTSU点云二值化

目录 一、算法原理二、代码实现三、结果展示1、原始点云2、二值化本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 最大类间方差法(Between-class scatter method)是一种用于分割的方法,它通过计算图…...

浔川python社获得全网博主原力月度排名泸州地区第二名!

今日&#xff0c;浔川python社在查看全网博主原力月度排名泸州地区时&#xff0c;一看就震惊啦&#xff01; 全网博主原力月度排名泸州地区排名榜单 全网博主原力月度排名泸州地区第二名为&#xff1a;浔川python社。 感谢粉丝们的支持&#xff01;浔川python社还会继续努力&a…...

第二站:Java——集合框架的深邃海洋(续)

### Java——集合框架的深邃海洋&#xff08;续&#xff09; 在我们的Java集合框架探索之旅中&#xff0c;我们已经涉足了基本操作、高级特性&#xff0c;现在让我们深入探讨一些特定场景下的应用和进阶技巧&#xff0c;比如集合的分区操作、分组、并行流的性能考量&#xff0…...