【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的内容,感谢大家的支持。♥

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

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

相关文章

五分钟“手撕”栈

实现代码放开头&#xff0c;供大家学习与查阅 目录 一、实现代码 二、什么是栈 三、栈的常见操作 底层实现是链表。 入栈 出栈 四、Stack的使用 五、栈的习题 第一题 第二题 第三题 第四题 第五题 第六题 第七题 六、栈、虚拟机栈、栈帧的区别 目录 一、…

Request

一、Request介绍 在计算机网络中&#xff0c;"Request"&#xff08;请求&#xff09;通常指的是客户端向服务器发送的请求消息&#xff0c;用于获取特定资源或执行特定操作。在Web开发中&#xff0c;"Request"通常指的是HTTP请求&#xff0c;用于客户端与服…

信号稳定,性能卓越!德思特礁鲨系列MiMo天线正式发布!

作者介绍 礁鲨系列天线&#xff0c;以其独特的外观设计和强大的性能&#xff0c;成为德思特Panorama智能天线家族的最新成员。这款天线不仅稳定提供5G、WIFI和GNSS信号&#xff0c;更能在各类复杂环境中展现出卓越的性能。它的设计灵感来源于海洋中的礁鲨&#xff0c;象征着力量…

内存管理【C++】

内存分布 C中的内存区域主要有以下5种 栈&#xff08;堆栈&#xff09;&#xff1a;存放非静态局部变量/函数参数/函数返回值等等&#xff0c;栈是向下增长的【地址越高越先被使用】。栈区内存的开辟和销毁由系统自动执行 堆&#xff1a;用于程序运行时动态内存分配&#xff…

电脑丢失api-ms-win-crt-runtime-l1-1-0.dll的多种修复方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“api-ms-win-crt-runtime-l1-1-0.dll丢失”。这个错误通常发生在Windows操作系统中&#xff0c;它表示一个动态链接库文件丢失或损坏。这个问题可能会导致某些应用程序无法正常运行&#xf…

大型企业用什么文件加密软件,五款适合企业的文件加密软件

大型企业在选择文件加密软件时&#xff0c;通常会倾向于那些能够提供全面数据保护、具有高度可定制性、易于管理且能适应复杂组织结构的解决方案。以下是一些适合大型企业使用的文件加密软件&#xff1a; 1.域智盾软件&#xff1a; 作为一款企业级文件加密软件&#xff0c;支持…

曲面细分技术在AI去衣中的创新应用

引言&#xff1a; 随着人工智能技术的飞速发展&#xff0c;其在图像处理领域的应用日益广泛。其中&#xff0c;AI去衣技术因其独特的应用场景而备受瞩目。在这一技术的发展过程中&#xff0c;曲面细分技术发挥了至关重要的作用。本文将深入探讨曲面细分技术在AI去衣中的作用及其…

C语言-单精度和双精度浮点型

文章目录 一、遇到的问题二、解决方案三、问题根因float和double的区别&#xff1a; 总结-浮点数 一、遇到的问题 将NXP项目的代码移植到RH850F1K的项目上时&#xff0c;程序运行异常&#xff1a; u16Volt (uint16)((double)u16ADVal * (double)6.3) 执行到这一行程序就跑飞了…

vue3可以快速简单的操作dom元素了

再也不需要用document.getElementById("myElement")的这种方式来对dom元素进行操作了 我们需要使用模板引用——也就是指向模板中一个 DOM 元素的 ref。我们需要通过这个特殊的 ref attribute 来实现模板引用&#xff1a; <script setup> import { ref, onMo…

wafw00f一键检测目标防火墙信息(KALI工具系列十五)

目录 1、KALI LINUX简介 2、wafw00f工具简介 3、在KALI中使用lbd 3.1 查看可检测的防火墙对象 3.2 目标防火墙种类检测 3.3 目标防火墙详细信息检测 3.4 将检查结果输出 4、总结 1、KALI LINUX简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版&#xff0c;广…

最好的电脑数据恢复软件是什么

由于硬件故障、恶意软件攻击或意外删除而丢失文件可能会造成巨大压力。数据丢失会扰乱日常运营&#xff0c;造成宝贵的业务时间和资源损失。在这些情况下&#xff0c;数据恢复软件是检索丢失或损坏数据的最简单方法。 数据恢复软件何时起作用&#xff1f; 对于 Windows 数据恢…

vue3组件传值---vue组件通过属性,事件和provide,inject进行传值

通过属性传值&#xff08;父传子&#xff09; vue的组件具有props自建属性&#xff08;自定义名称&#xff0c;类似于class&#xff0c;id的属性&#xff09;&#xff0c;通过这个属性&#xff0c;父组件可以向子组件传递参数&#xff0c;从而实现组件之间的信息传递&#xff0…

CSDN UI 2024.06.01

当我们的栏目很多的时候&#xff0c;通过【置顶】来排列顺序是很麻烦的&#xff0c;应该加一列&#xff0c;设置优先级别。太难用了 或者加两个按钮【上移】 【下移】

极验4点选逆向 JS逆向分析 最新版验证码

目录 声明&#xff01; 一、请求流程分析 二、加密参数w与payload 三、参数w生成位置 四、结果展示&#xff1a; 原创文章&#xff0c;请勿转载&#xff01; 本文内容仅限于安全研究&#xff0c;不公开具体源码。维护网络安全&#xff0c;人人有责。 声明&#xff01; 本文章…

升级笔记本

笔记本型号参数&#xff1a;Acer V5-573G CPU:I5 4200U 1.6GHz 最高2.6GHz 双核四线程 内存&#xff1a;4G 1600M DDR3L SO-DIMM 显卡&#xff1a;独立显卡NVIDIA GeForce GT 750M 硬盘&#xff1a;1T 5400转 屏幕&#xff1a;15.6英寸 1920*1080 【Acer V5-573G-54204G1…

WIFI 万[néng]钥匙 v5.0.10/v4.9.80 SVIP版!

WiFi Master Key v5.0.10/v4.9.80 WIFI万[Nng]钥匙APP是一款专业的网络连接工具&#xff0c;设计宗旨在于为用户提供方便快捷的WiFi接入方案。本应用集成了覆盖全国的大量免费WiFi热点信息&#xff0c;确保用户能够在不同地区快速而稳定地连接到互联网。此外&#xff0c;该应用…

atcoder350,351,352,353,354,355期部分题解

声明&#xff1a;有些题感觉已经说到很明白了&#xff0c;就先不写代码了&#xff0c;有空会补上 目录 350D: new friend 350E: toward 0 351D:Grid and Magnet 352D:permutation subsequence 353C: sigma problem 353D: another sigma problem 354C: atcoder magics …

神经网络与深度学习——第6章 循环神经网络

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第6章 循环神经网络 给网络增加记忆能力 延时神经网络 有外部输入的非线性自回归模型 循环神经网络 简单循环网络 循环神经网络的计算能力 循环神经网络的通用近似定理 图灵完备 应用到机器学习 序列到类…

python实现描述统计

数据基础情况 import numpy as np import pandas as pd import matplotlib.pyplot as pyplot pd.options.display.max_rows 10##最多输出10行数据 data_url https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-ST0151EN-SkillsN…

数据整理操作及众所周知【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…