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

news2024/10/6 6:44:10

在这里插入图片描述

🔥个人主页: 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链表的迭代器构建third
    std::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 ints
	std::list<int> second(5);     // list of 5 zero-initialized ints

	second = 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 5

    it = 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.coloradmin.cn/o/1789018.html

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

相关文章

一文读懂筛选控件设计

​筛选的作用是缩小展示范围&#xff0c;筛选控件有时会用于“频道切换”。比如内容型或电商产品&#xff0c;用tab切换不同频道&#xff0c;每个频道内有自己的形态。 而到了 B 端产品&#xff0c;如一个 CRM 系统当中&#xff0c;筛选的逻辑比移动端的复杂&#xff0c;有&…

【qt15】windeployqt 安装依赖

debug模式vs可以使用qt插件新建qt文件 D:\Qt15\5.15.2\msvc2019\bin\windeployqt.exe Warning: Cannot find Visual Studio installation directory, VCINSTALLDIR is not set.D:\Qt15\5.15.2\msvc2019\bin\windeployqt.exe .\filecopier.exeWindows PowerShell Copyright (C) …

【成品论文】2024年数学建模国赛B题成品论文分享(点个关注,后续会更新)

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的蓝色字体链接&#xff0c;那是获取资料的入口&#xff01; 点击链接加入群聊【2024国赛资料合集】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kCe9u9pqQeBrMHgupi-R078l9TuU0RwSl&authKeyRjsYS3Piiw…

Flutter开发效率提升1000%,Flutter Quick教程之定义Api(三)

将tab键切换到Response&#xff0c;会出现这么一个界面 这是添加api返回的json数据。比如我们添加一个json数据。 添加完json数据后&#xff0c;右上角有一个删除按钮。要换json数据的话&#xff0c;可以点击清除再重新输入。 这时候&#xff0c;左边的面板上还会显示出 这个的…

代理记账公司的五大问题及其解决方案

代理记账公司是现代企业管理中不可或缺的一部分&#xff0c;它为企业的日常运营提供了专业、高效的服务&#xff0c;随着行业的发展和竞争的加剧&#xff0c;代理记账公司的面临的问题也日益突出&#xff0c;这些问题主要表现在以下几个方面&#xff1a; 业务流程不规范 许多代…

CodeBlocks官方主题颜色更换及方法

文章目录 一、前言二 、用工具导入配置文件2.1 运行 cb_share_config.exe文件2.2 替换文件2.3 设置主题 三、配置主题3.1 步骤13.2 步骤23.3 步骤3 四、设置光标4.1 配置字体4.2 展示 行号 五、设置左边行号区域部分六、设置完后的效果七、下载地址 一、前言 Codeblocks 默认的…

【全开源】同城跑腿系统源码小程序(FastAdmin+ThinkPHP+Uniapp)

让生活更便捷的一站式服务 一款基于FastAdminThinkPHPUniapp开发的同城跑腿小程序&#xff0c;支持帮取、帮送模式&#xff0c;包含用户端、骑手端、运营后台&#xff0c;支持一键接单/抢单&#xff0c; 为跑腿团队提供技术解决方案&#xff0c;无加密源码&#xff0c;可私有化…

.Net 基于.Net8开发的一个Asp.Net Core Webapi后端框架

1.项目结构 该项目是基于.net8开发的Asp.Net Core WebApi后端服务,集成了Efcore,Autofac,Jwt,AutoMapper,Serilog,Quartz,MiniExcel等组件。该框架简单易上手&#xff0c;没有额外的学习成本; 该项目采用了多层结构设计&#xff0c;有利于解耦&#xff0c;包含公共层&#xff0…

AI绘画SD入门教程:ControlNet篇-Canny边缘检测预处理器

大家好&#xff0c;我是向阳 在本篇中&#xff0c;我来讲讲如何使用预处理器和辅助模型&#xff0c;分别都有些什么作用。 &#x1f4a1; 这里说明一下当你调用预处理器而辅助模型显示为无的几种原因&#xff1a; 当已载入SD1.5的模型时&#xff0c;CannyXL的辅助模型不会显示…

ch5链路层和局域网

回顾TCP/IP参考模型,明确链路层和物理层在整个模型中的地位,简要提出链路层要解决的问题是单段链路的数据传输,物理层解决的是数字信号与电气信号之间的相互转换。 链路层概述 节点:主机和路由器(包括网桥和交换机) 链路:沿着通信路径连接相邻节点的通信信道 有线链路 无…

Redis缓存(笔记一:缓存介绍和数据库启动)

目录 1、NoSQL数据库简介 2、Redis介绍 3、Redis(win系统、linux系统中操作) 3.1 win版本Redis启动 3.2 linux版本Redis启动 1、NoSQL数据库简介 技术的分类&#xff1a;&#xff08;发展史&#xff09; 1、解决功能性的问题&#xff1a;Java、Jsp、RDBMS、Tomcat、HTML、…

【面试干货】什么是内连接、外连接、交叉连结、笛卡尔积?

【面试干货】什么是内连接、外连接、交叉连结、笛卡尔积&#xff1f; 1、内连接&#xff08;Inner Join&#xff09;2、左外连接&#xff08;Left Outer Join&#xff09;3、右外连接&#xff08;Right Outer Join&#xff09;4、全外连接&#xff08;Full Outer Join&#xff…

被斯坦福抄作业了?在线体验下:国产大模型确实越来越棒啦!

抄袭&#xff1f; 这里不做评价了&#xff1a; 官方仓库 地址&#xff1a;miniCPM-Llama3-V-2_5 免费在线体验地址 链接&#xff1a;Llama3-V-2_5 模型能力&#xff1a; 模型实际体验 问他什么模型&#xff1a;&#xff08;可能用了它的数据集吧&#xff09; 图片分析…

CrossPrefetch: Accelerating I/O Prefetching for Modern Storage——论文泛读

ASPLOS 2024 Paper 论文阅读笔记整理 问题 目前计算设备和存储设备之间的性能差距仍然很大。因此&#xff0c;主内存缓存和缓冲区被广泛用于操作系统、用户级文件系统[32]和I/O运行时&#xff0c;在隐藏性能差距和减少I/O瓶颈方面发挥关键作用[23&#xff0c;26&#xff0c;3…

1. lvs负载均衡

lvs负载均衡 一、集群技术概述1、集群技术类型2、负载均衡技术3、高可用技术 二、负载均衡 LVS1、LVS介绍2、负载均衡策略/算法3、LVS设计模式3.1 NAT模式的注意事项 三、LVS nat模式的实现1、确认后端服务器网关正确2、安装ipvsadm软件3、开启路由转发4、创建虚拟服务5、添加后…

EasyV开发人员的使用说明书

在可视化大屏项目时&#xff0c;开发人员通常需要承担以下任务&#xff1a; 技术实现&#xff1a;根据设计师提供的设计稿&#xff0c;利用前端技术&#xff08;如HTML、CSS、JavaScript等&#xff09;和后端技术&#xff08;根据具体项目需求&#xff0c;可能是Java、Python、…

冯喜运:6.5今日黄金原油行情怎么看及日内操作策略

【黄金消息面分析】&#xff1a;周三&#xff08;6月5日&#xff09;亚市早盘&#xff0c;现货黄金窄幅震荡&#xff0c;目前交投于2328.13美元/盎司附近。黄金价格周二下跌超过1%&#xff0c;原因是美元在本周晚些时候美国就业数据公布前趋于稳定&#xff0c;该数据可能为美联…

【数据结构】图论中求最短路径——迪杰斯特拉算法(Dijkstra)、弗洛伊德算法(Floyd)

目录 最短路径 (*)迪杰斯特拉算法&#xff08;Dijkstra&#xff09;迪杰斯特拉算法&#xff08;Dijkstra&#xff09;的算法原理&#xff1a; 弗洛伊德算法&#xff08;Floyd&#xff09;弗洛伊德算法&#xff08;Floyd&#xff09;的算法原理&#xff1a;弗洛伊德算法的&#…

Ubuntu server 24 (Linux) 普通用户不能sudo 也不能使用root登录 忘记root密码 修复解决方案

一 普通用户无法sudo&#xff0c;同时也没有其他用户可用 #test用户使用sudo报错&#xff0c;没有权限 testtest:~$ sudo vi /etc/sudoers [sudo] password for test: test is not in the sudoers file. 二 关闭ubuntu 服务器&#xff0c;重新开机 按下ESC 键 1 出现GRUB…

LLM推理加速原理(一)

1.大语言模型的基本结构 transfomer block: 输入--->正则化-->qkv三个矩阵层(映射到三个不同空间中)---->q,k,v之后self attention进行三0合一---->线性映射,正则化。 2.大语言模型的推理 目前主流的语言大模型都采用decoder-only的结构,其推理过程由两部分…