【C++】STL---list基本用法介绍

news2024/11/26 19:47:00

个人主页:平行线也会相交💪
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C++之路】💌
本专栏旨在记录C++的学习路线,望对大家有所帮助🙇‍
希望我们一起努力、成长,共同进步。🍓
在这里插入图片描述

list是STL中的一种容器,底层其实就是一个双向链表

既然底层实现是双向链表,所以list重要的一点就是插入和删除操作的时间复杂度为常数时间O(1),这是因为链表的结构不需要像数组一样进行内存重排。

当然,如果要频繁访问链表中的元素,需要沿着链表进行遍历,这导致list容器访问操作的时间复杂度为O(n)。
在这里插入图片描述

下面将对list中的常见的用法进行一一介绍。

目录

  • 一、创建变量
  • 二、增删查改
    • 1️⃣插入元素
    • 2️⃣删除
    • 3️⃣查找和修改
  • 三、list大小计算
  • 四、迭代器遍历
  • 五、常见算法
    • 1️⃣排序
    • 2️⃣删除指定值-remove()
    • 3️⃣链表元素转移-splice()

一、创建变量

下面链表变量的创建:

list<int> it1;//创建一个空的list
list<int> it2 = { 1,2,3,4,5 };//创建一个带有初始元素的list

二、增删查改

1️⃣插入元素

插入元素总共分为三种:尾插、头插、任意位置插入
尾插(push_back()):

list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);

头插(push_front()):

list<int> lt1;
lt1.push_front(1);
lt1.push_front(2);

任意位置插入删除(insert()):

//在第三个位置进行插入10
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
list<int>::iterator it = lt1.begin();
for (size_t i = 0; i < 2; i++)
{
	it++;
}
lt1.insert(it, 10);
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

2️⃣删除

//删除的节点中数据为3的节点
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;

list<int>::iterator it = lt1.begin();
it = find(lt1.begin(), lt1.end(), 3);
//判断是否查找成功
if (it != lt1.end())
{
	lt1.erase(it);
	//节点此时已经被删除了,当前的迭代器失效
	//*it *= 10;
}
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

下面来删除list中的偶数元素:

list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);
	lt1.push_back(4);

	list<int>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		if (*it % 2 == 0)
		{
			it = lt1.erase(it);
		}
		else
		{
			it++;
		}
	}
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

在这里插入图片描述

3️⃣查找和修改

这里我们需要注意一点:std::list没有提供内置的find()函数

原因主要有两点:
第一遍历代替索引访问:由于std::list是一个双向链表,不支持通过索引来直接访问元素。相反,要访问或查找元素,需要使用迭代器进行迭代操作

第二:链表的特点是插入和删除元素的时间复杂度为O(1),但访问元素的时间复杂度为O(n),其中n是链表长度。相比之下,std::vector的访问时间复杂度为O(1)。由于链表不支持快速随机访问,使用线性搜索遍历整个链表可能是更高效的操作

举例:

//在链表中查找节点中数据为3的节点,如果查找成功,将该数据的数据*10
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;

list<int>::iterator it = lt1.begin();
it = find(lt1.begin(), lt1.end(), 3);
//判断是否查找成功
if (it != lt1.end())
{
	//查找成功则将迭代器位置的数据*10
	*it *= 10;
}
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;
}

在这里插入图片描述
可以看到查找成功并将该节点的数据*10。

三、list大小计算

std::list提供了size()函数,用于返回链表中元素的数量
在这里插入图片描述

四、迭代器遍历

list<int> lt1 = { 1,2,3,4,5 };

for (auto it = lt1.begin(); it != lt1.end(); it++)
{
	(*it)++;
	cout << *it << " ";
}
cout << endl;

在这里插入图片描述

五、常见算法

1️⃣排序

list<int> lt = { 12,56,2,95,35,78,47 };
lt.sort();
for (auto e : lt)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

2️⃣删除指定值-remove()

这里需要注意的是:remove()函数会移除链表中所有与指定值相等的元素,而不仅仅是第一个匹配项。这与erase()函数的行为不同,erase()函数通常只移除第一个匹配项。

list<int> lt1 = { 12,56,2,95,35,78,47 };
lt1.remove(56);
for (auto e : lt1)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述
如果链表中没有想要删除的指定值,则remove()函数不会作任何事情,也不会报错。请看举例:
在这里插入图片描述

3️⃣链表元素转移-splice()

在STL中,std::list提供了splice()函数,用于将一个链表的元素或者一个元素范围转移到另一个链表中。

splice()函数共有3个版本:

void splice(const_iterator position, list& x);
void splice(const_iterator position, list& x, const_iterator i);
void splice(const_iterator position, list& x, const_iterator first, const_iterator last);

下面对splice()函数的3个版本进行举例,请看:

list<int> lt1 = { 1,2,3,4 };
list<int> lt2 = { 10,20,30,40 };

list<int> lt3 = { 1,2,3,4 };
list<int> lt4 = { 10,20,30,40 };

list<int> lt5 = { 1,2,3,4 };
list<int> lt6 = { 10,20,30,40 };

// 将lt2中的所有元素移动到lt1的末尾
lt1.splice(lt1.end(), lt2);
for (auto e : lt1)
	cout << e << " ";
cout << endl;

// 将lt4中的第二个元素移动到lt3的开头
auto it3 = lt3.begin();
auto it4 = lt4.begin();
it4++;
lt3.splice(it3, lt4, it4);
for (auto e : lt3)
	cout << e << " ";
cout << endl;

//将lt6中的20 30 40移动到lt5的最后位置
auto first = ++lt6.begin();
auto end = lt6.end();
lt5.splice(lt5.end(), lt6, first, end);
for (auto e : lt5)
	cout << e << " ";
cout << endl;

运行结果如下:
在这里插入图片描述

好了,以上就是本文的全部内容,主要对list的一些基本语法和用法进行了介绍。
就到这里吧,再见啦友友们!!!

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

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

相关文章

文件批量智能归类

在日常工作中我们会经常碰到同一个文件夹里面多个文件有视频&#xff0c;图片&#xff0c;或视频标题名称不一样&#xff0c;图片名称不一样&#xff0c;整个文件夹看下来很混乱&#xff0c;需要找一个文件工花费很长时间去找&#xff0c;一个一个用眼睛去看&#xff0c;看久眼…

Linux开发工具使用

Linux开发工具使用 vim1.vim的基本概念2.vim三种模式的切换3.底行模式的基础操作4.命令模式下的基础操作5.vim的配置 yum1.yum的概念2.yum的基础操作 gcc/g1.gcc/g的概念2.一个C/C程序形成的过程3.gcc/g基本使用 make和makefile1.基础概念2.makefile【1】生成【2】清理 调试器g…

2023国际高校数学建模竞赛B题三星堆文物原创论文讲解

大家好呀&#xff0c;从昨天发布赛题一直到现在&#xff0c;总算完成了国际高校数学建模竞赛B题完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 B题论文共28页&#xff0c;一些…

docker php 容器安装redis和mongodb扩展

一、背景 很多项目(几乎所有)都有用到redis和mongodb来存储数据&#xff0c;php没有自带这些扩展&#xff0c;需要手动安装 二、PHP redis扩展安装步骤 这里以php8.2版本容器为例&#xff0c;以下命令中‘php82’均为容器名称&#xff0c;需要更换为你自己的实际名称&#x…

JZ31 栈的压入、弹出序列-C++

题目来源&#xff1a;牛客网 题目描述&#xff1a; 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xff0c;序列4,5,3,2,1是该压栈序列…

List如何正确删除元素

public static void main(String[] args) {List<Integer> list Lists.newArrayList(1, 2, 3, 4, 5);list.forEach(item -> {if (item 3) {list.remove(3);}});} 使用foreach删除集合元素的时候&#xff0c;有可能会报错&#xff0c;报错信息如下&#xff1a; 这是因…

【docker】docker

目录 一、docker概念二、docker安装(centos7)三、docker架构3.1 镜像image3.2 容器container 四、配置docker镜像加速器五、docker命令5.1 docker服务命令5.2 docker镜像命令5.3 docker容器命令 六、docker容器的数据卷6.1 容器卷概念及作用6.2 配置数据卷6.3 挂载示例6.4 数据…

【Linux】多线程概念理论

目录 1 什么是线程&#xff1f; 2 线程的优点 3 线程的缺点 4 线程异常 5 线程用途 6 Linux线程和进程对比 1 什么是线程&#xff1f; 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列…

【ARMv8 SIMD和浮点指令编程】NEON 移位指令——左右移位之术

NEON 移位指令主要涉及逻辑移位、算术移位两大类,同时下面还介绍了两个移位插入指令。 一、逻辑移位 1.1 SHL 左移(立即数)。该指令从向量中读取每个值,将每个结果左移一个立即值,将最终结果写入向量,并将向量写入目标 SIMD&FP 寄存器。 标量 SHL <V><d…

hive之存储优化

从这里开始就是hive调优阶段&#xff0c;怎么让hive跑的更快。 分区表和分桶表都是从存储方向进行优化。 目录 分区表&#xff1a; 概念&#xff1a; 代码&#xff1a; load填充数据&#xff1a; insertselect填充数据&#xff1a; 需求&#xff1a; 分区表基本操作 (一)…

vue3自定义日历

原理 现在的日历分为两种开头&#xff1a; 1. 日, 一, 二, 三, 四, 五, 六 2. 一, 二, 三, 四, 五, 六, 日一行7个日期&#xff0c;一共6行 其实不管哪种都一样&#xff0c;首先要确定第一行1号在哪个位置。 如果说是 日, 一, 二, 三, 四, 五, 六&#xff0c;那么getDay()是几…

了解Unity编辑器之组件篇UI(一)

UI组件&#xff1a;提供了用户交互&#xff0c;信息展示&#xff0c;用户导航等功能 一、Button&#xff1a;用于响应用户的点击事件 1.Interactable&#xff08;可交互&#xff09;&#xff1a;该属性控制按钮是否可以与用户交互&#xff0c;如果禁用则按钮无法被点击。可以通…

为什么TM服务器要安装php~

"想像力比知识更重要。因为知识是有限的&#xff0c;而想像力是无限&#xff0c;它包含了一切&#xff0c;推动着进步&#xff0c;是人类进化的源泉。 -- 爱因斯坦 为什么服务器要安装php~ 服务器为什么安装PHP (2023年) 导读&#xff1a;今天来给各位分享关于服务器为什么…

List有值二次转换给其他对象报null

List<PlatformUsersData> listData platformUsersMapper.selectPlatformUserDataById(data); users.setPlatformUsersData(listData);为什么listData 有值&#xff0c;users.getPlatformUsersData&#xff08;&#xff09;仍然为空在这段代码中&#xff0c;我们假设listD…

初识C++ ------ 引用、内联函数、auto关键字、基于范围的for循环、指针空值

文章目录 引用特点引用和指针的区别 内联函数概念 auto 关键字基于范围的for循环指针空值 nullptr &#xff08;C11&#xff09; 引用 特点 传引用返回&#xff1a;提高了效率&#xff0c;可以修改返回对象&#xff0c;传引用传参&#xff1a;提高效率&#xff0c;输出型参数。…

解密动态内存管理的奥秘(含内存4个函数)

目录 一.为什么存在动态内存管理 二.动态内存函数的介绍 1. malloc函数&#xff08;memory alloc 内存开辟&#xff09; 函数介绍&#xff1a; malloc函数使用举例代码&#xff1a; 2.free&#xff08;释放&#xff09; 函数介绍&#xff1a; 代码的示例&#xff1a…

Linux 网络通信epoll详解( 10 ) -【Linux通信架构系列 】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the…

《网络是怎样连接的》(二.1)

(83条消息) 《网络是怎样连接的》&#xff08;一&#xff09;_qq_38480311的博客-CSDN博客 本文主要取材于 《网络是怎样连接的》 第二章。 目录 &#xff08;1&#xff09;创建套接字 &#xff08;2&#xff09;连接服务器 &#xff08;3&#xff09;收发数据 &#xf…

文本预处理——文本处理的基本方法

目录 什么是分词jieba分词特性精确模式分词全模式分词搜索引擎模式分词使用用户自定义词典 命名实体识别词性标注 什么是分词 jieba分词特性 精确模式分词 import jieba content工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作 print(jieba.lcut(co…

《零基础入门学习Python》第055讲:论一只爬虫的自我修养3:隐藏

0. 请写下这一节课你学习到的内容&#xff1a;格式不限&#xff0c;回忆并复述是加强记忆的好方式&#xff01; 上节课我们说过了&#xff0c;有一些网站比较痛恨爬虫程序&#xff0c;它们不喜欢被程序所访问&#xff0c;所以它们会检查链接的来源&#xff0c;如果说来源不是正…