十三、list 类

news2024/11/15 4:15:40

Ⅰ . list 的介绍和使用

01 初识 list

我们已经学习过 string 和 vector 了,想必大家已经掌握了查文档的能力

现在我们去学习如何使用 list ,最好仍然打开文档去学习

list - C++ Reference

① list 是一个顺序容器

允许在任意位置进行 O(1) 插入和删除的顺序容器,并提供双向迭代器

② list 底层是双向链表

双向链表中每个元素存储在互不相关的独立结点中,在结点中通过两个指针指向其前后元素

③ list 与 forward_list 非常相似

最大的不同就是 forward_list 是单链表,只能向前迭代

④ 与其他序列式容器相比(array,vector,deque)

list 通常在任意位置进行插入、删除元素的效率更高,因为是 O(1)

list 和 forward_list 最大的缺陷是不支持随机位置的随机访问 举个例子:

如果要访问 list 中的第六个元素,必须从已知位置(如头部或尾部)迭代到该位置

在这段位置上迭代需要线性时间的时间开销,同时,list 还需要一些额外空间

以保存每个结点的相关联信息

02 创建 list

代码实现:

#include<iostream>
#include<list>
using namespace std;

int main()
{
	list<int> l;

	return 0;
}

Ⅱ . list 的修改操作

01 修改操作的函数

02 push_back 

在 list 尾部插入值为 val 的元素

代码实现:

#include<iostream>
#include<list>
using namespace std;

int main()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	return 0;
}

我们现在来打印一下

首先思考一个问题,还能使用下标 + 方括号的方式遍历嘛?

不行 因为 list 是链表,是通过指针连接的,所以不支持随机访问

而 string 和 vector 可以,因为它们的物理结构是连续的

迭代器遍历:

#include<iostream>
#include<list>
using namespace std;

int main()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	// 迭代器
	list<int>::iterator it = l.begin();
	while (it != l.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	return 0;
}

运行结果如下:

范围 for 就更简单了:

	// 范围for
	for (auto e : l)
		cout << e << " ";
	cout << endl;

如果我们想倒着遍历,我们可以使用反向迭代器

使用 rbegin() 和 rend()

反向迭代器:

	// 反向迭代器
	list<int>::reverse_iterator rit = l.rbegin();
	while (rit != l.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

运行结果如下:

03 push_front

在 list 头部插入值为 val 的元素

代码实现:

void list_test2()
{
	list<int> l;
	l.push_front(1);
	l.push_front(2);
	l.push_front(3);
	l.push_front(4);

	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

04 pop_back

删除 list 中的最后一个元素

void list_test3()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	cout << "删除前:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.pop_back();
	cout << "删除后:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

如果表内没有元素,进行删除操作,会触发断言

05 pop_front

删除 list 中的第一个元素

void list_test4()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	cout << "删除前:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.pop_front();
	cout << "删除后:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

06 insert

在上一节讲解 vector 实现的时候,我们对迭代器失效的问题进行了简单探讨

这里 list 的 insert 同样会涉及迭代器失效的问题,我们在模拟实现的时候再进行探讨

07 clear

清空 list 中的有效元素,使容器大小的 size 变为 0

代码演示:

void list_test5()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	cout << "清空前:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.clear();
	cout << "清空后:";
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

08 erase

代码演示:

void list_test6()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	list<int>::iterator it = find(l.begin(), l.end(), 4);
	if (it != l.end())
	{
		l.erase(it);
	}
	else
	{
		cout << "没找到";
	}
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

Ⅲ . list 容量操作

01 size 返回有效结点个数

代码演示:

void list_test7() 
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	for (auto e : l) 
		cout << e << " "; 
	cout << endl;

	cout << "有效节点个数:";
	cout << l.size() << endl;
}

运行结果如下:

02 empty 检测容器是否为空

empty 是用来检测容器是否为空的,如果为空则返回 true,否则返回 false。

代码演示:

void list_test8()
{
	list<int> l;
	l.empty() == true ? cout << "为空" : cout << "不为空";
}

运行结果如下:

 

03 resize 调整容器大小

list 中的 resize 和之前的 resize 的 "扩容" 有点不一样,它没有容量。

这里的 resize 是调整容器的大小,使其包含 n​ 个元素。

代码演示:

void list_test9()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.resize(10, 5);
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

Ⅳ . list 的其他操作

01 reverse 逆置

代码演示:

void list_test10()
{
	list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.reverse();
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

02 sort 排序

代码演示:

void list_test11()
{
	list<int> l;
	l.push_back(4);
	l.push_back(2);
	l.push_back(6);
	l.push_back(1);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.sort();
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

03 unique 去重

去重之前是有要求的,去重之前一定要先排序,如果不排序可能会去不干净

代码演示:

void list_test12()
{
	list<int> l;
	l.push_back(2);
	l.push_back(1);
	l.push_back(2);
	l.push_back(1);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	l.sort();
	cout << "去重后:";
	l.unique();
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

如果不排序,会导致去不干净:

void list_test12()
{
	list<int> l;
	l.push_back(2);
	l.push_back(1);
	l.push_back(2);
	l.push_back(1);
	for (auto e : l)
		cout << e << " ";
	cout << endl;

	//l.sort();
	cout << "去重后:";
	l.unique();
	for (auto e : l)
		cout << e << " ";
	cout << endl;
}

04 remove

remove 只需要给一个元素的值,它就可以自己找自己删

代码演示:

void list_test13() 
{
	list<int> l;
	l.push_back(10);
	l.push_back(20);
	l.push_back(30);
	l.push_back(40);
	for (auto e : l) 
		cout << e << " "; 
	cout << endl;

	// 如果删一个存在的元素
	l.remove(10);
	for (auto e : l) 
		cout << e << " "; 
	cout << endl;

	// 如果待删元素不存在
	l.remove(0);
	for (auto e : l) 
		cout << e << " "; 
	cout << endl;
}

运行结果如下:

 05 splice 接合

简单来说就是把一个链表转移到另一个链表中

代码演示:

void list_test14()
{
	list<int> l1;
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	cout << "l1:";
	for (auto e : l1)
		cout << e << " ";
	cout << endl;

	list<int> l2;
	l2.push_back(10);
	l2.push_back(20);
	l2.push_back(30);
	cout << "l2:";
	for (auto e : l2)
		cout << e << " ";
	cout << endl;

	list<int>::iterator pos = l1.begin();
	// 把l2的内容接到l1的begin()前面
	l1.splice(pos, l2);
	cout << "接合后";
	for (auto e : l1)
		cout << e << " ";
	cout << endl;
}

运行结果如下:

 

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

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

相关文章

Blazor开发框架Known-V2.0.7

V2.0.7 Known是基于Blazor的企业级快速开发框架&#xff0c;低代码&#xff0c;跨平台&#xff0c;开箱即用&#xff0c;一处代码&#xff0c;多处运行。 官网&#xff1a;http://known.pumantech.comGitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;http…

2024.8.7(SQL语句)

一、回顾 1、主服务器 [rootslave-mysql ~]# yum -y install rsync [rootmaster-mysql ~]# yum -y install rsync [rootmaster-mysql ~]# tar -xf mysql-8.0.33-linux-glibc2.12-x86_64.tar [rootmaster-mysql ~]# ls [rootmaster-mysql ~]# tar -xf mysql-8.0.33-linux-glib…

ssd202d-添加4g模块-HM609

1.lsusb要看到设备 2.驱动部分要打开usb识别,rndis支持 diff --git a/kernel/arch/arm/configs/infinity2m_spinand_ssc011a_s01a_minigui_defconfig b/kernel/arch/arm/configs/infinity2m_spinand_ssc011a_s01a_minigui_defconfig index e6a2e43b6..b0a60f4ee 100755 --- a/…

新品上市:ATA-401高压功率放大器技术参数、特点及应用

随着电子工程师不断增长的测试需求&#xff0c;安泰电子也在不断的拓展和研发新产品&#xff0c;近期安泰ATA-400系列高压功率放大器正式上线&#xff0c;又一单品新品测试仪器加入了Aigtek大家庭——ATA-401高压功率放大器。 关于ATA-401高压功率放大器 参数指标介绍&#xff…

基于vue框架的CIA报价平台的设计与实现1xv02(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,供应商,产品分类,产品信息,在线咨询,资质申请 开题报告内容 基于Vue框架的CIA报价平台的设计与实现 开题报告 一、选题背景 随着市场竞争的日益激烈&#xff0c;企业对于成本控制与效率提升的需求愈发迫切。在采购与供应链管理…

Unity URP 浅析两种模型透明Shader原理

Unity URP 浅析两种模型透明Shader原理 前言实现第一种 单个Pass写入深度的逻辑正确半透明模型第二种 2个Pass分工合作视觉正确的半透明模型 参考 前言 使用Unity做过半透明的朋友们都知道&#xff0c;这里面一堆坑&#xff0c;下面简单说两种透明Shader在ASE中的实现&#xf…

【仓颉】控制台输出中文乱码,cmd和powershell的解决方案

【仓颉】控制台输出中文乱码&#xff0c;cmd和powershell的解决方案 main(): Int64 {...println("这是仓颉")return 0 }临时修改编码页面 代码页国家(地区)或语言437美国850多语言(拉丁文 I)936中国 - 简体中文(GB2312)52936简体中文(HZ)65000Unicode (UTF-7)65001U…

Qt 计算器程序

下载链接&#xff1a; https://pan.baidu.com/s/1112o9eVbpC7FySsXRuP2xA 提取码: rd92 运行结果&#xff1a;

聚鼎科技:开一家抖音店铺到底还有前景不

在数字化的浪潮中&#xff0c;抖音不仅仅是一款短视频应用&#xff0c;它已经成为了一个新兴的商业平台&#xff0c;一个充满无限可能的市场。在这个平台上开一家店铺&#xff0c;就像在星辰大海中寻找自己的航向&#xff0c;既有挑战也有机遇。 “未来属于那些相信梦想之美的人…

【银河麒麟服务器操作系统·实例分享】虚机系统ssh无法正常登录访问,分析过程及处理建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 服务器环境以及配置 【机型】虚机 处理器&#xff1a; Kunpeng-920 内存&#xff1a; 32G 整机…

Linux 下的进程状态

文章目录 一、运行状态运行队列运行状态和运行队列 二、睡眠状态S状态D状态D状态产生的原因 三、暂停状态T状态t 状态 四、僵尸状态为什么有僵尸状态孤儿进程 一、运行状态 R状态&#xff1a;进程已经准备好随时被调度了。 运行队列 每个 CPU 都会维护一个自己的运行队列&am…

一文读懂GPU通信互联技术:GPUDirect、NVLink与RDMA

在高性能计算和深度学习领域&#xff0c;GPU的强大计算能力已成为不可或缺的工具。然而&#xff0c;随着模型复杂度和数据量的增加&#xff0c;单个GPU已无法满足需求&#xff0c;多个GPU甚至多台服务器协同工作成为常态。这就要求高效的GPU互联通信技术&#xff0c;以确保数据…

mesh格式转换:glb转ply——使用Blender烘焙贴图到顶点色

1. 导入glb文件 选择shading后&#xff0c;选中物体&#xff0c;就能看到下面的节点树。 2. 创建顶点颜色 这个时候我们可以看到模型的顶点颜色是纯白色的。 2. 将贴图付给材质 原来&#xff1a; 现在&#xff1a; 3. 切换渲染器并烘焙顶点颜色 第三行选择CPU渲染或者GPU…

Golang | Leetcode Golang题解之第331题验证二叉树的前序序列化

题目&#xff1a; 题解&#xff1a; func isValidSerialization(preorder string) bool {n : len(preorder)slots : 1for i : 0; i < n; {if slots 0 {return false}if preorder[i] , {i} else if preorder[i] # {slots--i} else {// 读一个数字for i < n &&…

Redis的持久化的策略

Redis的持久化的策略 官方文档说明 AOF持久化策略RDB持久化的策略 AOF持久化策略 AOF持久性记录服务器接收到的每个写操作&#xff0c;然后&#xff0c;可以在服务器启动时再次重播这些操作&#xff0c;重建原始数据集&#xff0c;使用与Redis协议本身相同的格式记录命令。…

kotlin协程之runBlocking

前言 上一篇: Callback转挂起函数 文章中,介绍了在Kotlin协程中如何把传统的回调风格的异步操作转换为协程风格的挂起函数,这个在开发过程中是非常常用的,主要用于把 callback 风格的代码转换为协程中的挂起函数,以便于我们在协程环境中调用。 但是,有时候我们也会遇到…

Socket进程间通信,从概念到实战(TCP,UDP,linux环境下C语言代码编写)

1、socket简述 Socket是一种通信机制&#xff0c;通过它可以在不同主机之间进行数据交换。在Socket编程中&#xff0c;有两种常见的通信模式&#xff1a;客户端-服务器模式和点对点模式。它基于TCP/IP协议栈&#xff0c;并使用IP地址和端口号来标识通信的目标。 2、Socket 基…

数据结构--树与二叉树

数据结构分类 集合 线性结构(一对一) 树形结构(一对多) 图结构(多对多) 数据结构三要素 1、逻辑结构 2、数据的运算 3、存储结构&#xff08;物理结构&#xff09; 树的概念 树的分类 满二叉树和完全二叉树 二叉排序树 平衡二叉树 二叉树分类总结 二叉树的存储结构 …

NVIDIA液冷技术革新:GB200 的挑战与机遇

英伟达 (Nvidia) 最近的一个创新与比特和字节无关。这是一项液冷技术创新。英伟达即将推出的 GB200 服务器机架将主要通过在硬件管道里循环的液体、而不是空气来冷却&#xff0c;该机架包含英伟达下一代 Blackwell 芯片。 英伟达发言人表示&#xff0c;该公司还在与供应商合作…

【人工智能】助力音乐产业

了解人工智能如何通过先进的制作和作曲工具改变音乐产业&#xff0c;创造创新的声音并重塑音乐创作。 人工智能在音乐行业中发挥着重要作用&#xff08;这是双关语&#xff09;。它影响着从艺术家创作音乐的方式到营销和发行的一切。鉴于人工智能的巨大力量&#xff0c;这项创新…