C++中的list容器

news2024/11/24 18:42:49

文章目录

    • list的介绍
    • list的使用
      • list的构造
      • list iterator的使用
      • list capacity
      • list元素访问
      • list modifiers
      • list的迭代器失效
    • list与vector的对比

list的介绍

  list是可以在常数范围内的任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代;
  list的底层是双向链表结构,双向链表中每个元素存储在不互相关的独立节点中,在节点中通过指针指向前一个与后一个元素;
  list与forward_list非常相似,forward_list是单链表,只能向前迭代;
  与其他的序列式容器相比,list通常在任意位置进行插入、移动元素的执行效率更好。但是list和forward_list最大的缺陷是不支持任意位置的随机访问,如果要访问某一位置,必须要从已知的位置开始迭代到对应位置,在这段位置上迭代需要线性的时间开销,list还需要一些额外的空间,用来保存每个节点的相关信息。

list的使用

list的构造

构造函数constructor接口说明
list(size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list(const list& x)拷贝构造函数
list(InputIterator first, InputIterator last)用[first, last]区间中的元素构造list
int main()
{
	list<int> first;
	list<int> second(4, 100);
	list<int> third(second.begin(), second.end());
	list<int> fourth(third);

	int myints[] = { 1, 2, 3, 4 };
	list<int> fifth(myints, myints + sizeof(myints) / sizeof(int));

	cout << "The contents of fifth are:";
	for (list<int>::iterator it = fifth.begin(); it != fifth.end(); it++)
		cout << *it << ' ';
	cout << endl;

	return 0;
}

在这里插入图片描述

list iterator的使用

函数声明接口说明
begin+end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin+rend返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置
cbegin+cend返回第一个元素的const_iterator+返回最后一个元素下一个位置的const_iterator
crbegin+crend返回第一个元素的const_reverse_iterator,即end位置,返回最后一个元素下一个位置的const_reverse_iterator,即begin位置

  begin与end是正向迭代器,对迭代器执行++操作,迭代器向后移动;
  rbegin与rend作为反向迭代器,对迭代器执行++操作,迭代器向前移动;
  cbegin+cend与crbegin+crend是C++11引入的。

int main()
{
	int myints[] = { 1, 2, 3, 4, 5 };
	list<int> mylist(myints, myints + 5);

	cout << "myints contains:";
	for (list<int>::iterator it = mylist.begin(); it != mylist.end(); it++)
		cout << ' ' << *it;
	cout << endl;

	cout << "myints backwards:";
	for (list<int>::reverse_iterator rit = mylist.rbegin(); rit != mylist.rend(); ++rit)
		cout << ' ' << *rit;
	cout << endl;

	return 0;
}

在这里插入图片描述

list capacity

函数声明接口说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数
max_size返回最大节点的个数
int main()
{
	list<int> mylist;
	int sum(0);

	cout << "max_size:" << mylist.max_size() << endl;
	cout << "1.size:" << mylist.size() << endl;

	for (int i = 1; i <= 10; i++)
		mylist.push_back(i);

	cout << "2.size:" << mylist.size() << endl;

	while (!mylist.empty())
	{
		sum += mylist.front();
		mylist.pop_front();
	}
	cout << "total:"<< sum << endl;

	return 0;
}

在这里插入图片描述

list元素访问

函数声明接口说明
front返回list的第一个节点中,值的引用
back返回list的最后一个节点中,值的引用
int main()
{
	list<int> mylist;
	mylist.push_back(77);
	mylist.push_back(33);
	mylist.push_back(22);

	cout << "front:" << mylist.front() << endl;
	cout << "back:" << mylist.back() << endl;

	mylist.front() -= 10;
	cout << "front:" << mylist.front() << endl;

	mylist.back() += 20;
	cout << "back:" << mylist.back() << endl;

	return 0;
}

在这里插入图片描述

list modifiers

函数声明接口说明
push_front在list首元素前插入元素
pop_front删除list中第一个元素
push_back在list尾部插入元素
pop_back删除list中最后一个元素
insert在list的任意位置插入元素
erase删除list任意位置的元素
swap交换两个list中的元素
clear清空list中的有效元素
int main()
{
	list<int> mylist(4, 0);
	list<int>::iterator it = mylist.begin();

	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	mylist.push_front(1);
	mylist.push_back(9);
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	mylist.pop_front();
	mylist.pop_back();
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	it = mylist.begin();
	mylist.insert(it, 10);
	it++;
	mylist.insert(it, 3, 5);
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	
	it = mylist.begin();
	it++;
	mylist.erase(it);
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	list<int>::iterator it1 = mylist.begin();
	list<int>::iterator it2 = mylist.begin();
	it1++;
	advance(it2, 5); // 迭代器移动三位
	mylist.erase(it1, it2);
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	return 0;
}

在这里插入图片描述

int main()
{
	list<int> mylist1(4, 1);
	list<int> mylist2(4, 2);

	cout << "mylist1:";
	for (list<int>::iterator it = mylist1.begin(); it != mylist1.end(); it++)
		cout << ' ' << *it;
	cout << endl;
	cout << "mylist2:";
	for (list<int>::iterator it = mylist2.begin(); it != mylist2.end(); it++)
		cout << ' ' << *it;
	cout << endl;

	mylist1.swap(mylist2);
	cout << "mylist1:";
	for (list<int>::iterator it = mylist1.begin(); it != mylist1.end(); it++)
		cout << ' ' << *it;
	cout << endl;
	cout << "mylist2:";
	for (list<int>::iterator it = mylist2.begin(); it != mylist2.end(); it++)
		cout << ' ' << *it;
	cout << endl;

	mylist1.clear();
	mylist1.push_back(9);
	mylist1.push_back(9);
	mylist1.push_back(9);
	cout << "mylist1:";
	for (list<int>::iterator it = mylist1.begin(); it != mylist1.end(); it++)
		cout << ' ' << *it;
	cout << endl;

	return 0;
}

在这里插入图片描述

list的迭代器失效

  迭代器失效即迭代器所指向的节点无效,也就是对应节点被删除了。因为list的底层结构为带头节点的双向循环链表,因为在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向删除节点的迭代器,其他迭代器不会受到影响。

int main()
{
	list<int> mylist(4, 0);
	list<int>::iterator it = mylist.begin();

	it = mylist.begin();
	it++;
	mylist.erase(it); // 这里it已经失效,如要使用需重新赋值
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	list<int>::iterator it1 = mylist.begin();
	list<int>::iterator it2 = mylist.begin();
	it1++;
	advance(it2, 5); // 迭代器移动三位
	mylist.erase(it1, it2);
	cout << "mylist:";
	for (it = mylist.begin(); it != mylist.end(); ++it)
		cout << ' ' << *it;
	cout << endl;

	return 0;
}

list与vector的对比

vectorlist
底层结构动态顺序表,一段连续的空间带头结点的双向循环链表
随机访问支持随机访问,访问某个元素的效率为O(1)不支持随机访问,访问某个元素的效率为O(N)
插入和删除任意位置插入和删除效率低,需要移动元素O(N),插入时需要增容,开辟新空间,释放旧空间任意位置插入和删除效率高,不需要移动元素
空间利用率底层为连续空间,不容易造成内存碎片,空间利用率高,缓存利用率高底层节点动态开辟,小节点容易造成内存碎片,空间利用率低
迭代器原生态指针对原生态指针(节点指针)进行封装
迭代器失效在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,导致原来的迭代器失效,删除时,当前迭代器需要重新赋值否知会失效插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响
使用场景需要高效存储,支持随机访问,不关心插入删除效率大量插入和删除操作,不关心随机访问

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

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

相关文章

FFMPEG中的filter使用二

上一篇我们在使用滤镜时是手动创建各种滤镜&#xff0c;然后根据处理链路手动链接不同的过滤器&#xff0c;有助于我们理解滤镜的流程。这一篇我们使用参数形式&#xff0c;让ffmpeg自动帮我们创建和链接过滤器&#xff0c;这样可以减少代码量&#xff0c;同时我们可以先使用参…

学系统集成项目管理工程师(中项)系列15_质量管理

1. 质量&#xff08;Quality&#xff09;的定义 1.1. 反应实体满足主体明确和隐含需求的能力的特性总和 1.2. 明确需求是指在标准、规范、图样、技术要求、合同和其他文件中用户明确提出的要求与需要 1.3. 隐含需求是指用户和社会通过市场调研对实体的期望以及公认的、不必明…

thinkphp路由,请求和响应

文章目录 定义获取路由后面的参数跨域请求请求响应 定义 thinkphp定义路由一般在route路由下的app.php中 下面这是一个简单的路由 Route::rule(admin/login,/app/controller/Admin/login)->middleware(\app\middleware\MyMiddleware::class);该路由表示当访问admin/login时…

人工智能课程笔记(7)强化学习(基本概念 Q学习 深度强化学习 附有大量例题)

文章目录 1.强化学习与深度学习的区别2.强化学习中的基本概念3.强化学习、有监督学习和无监督学习的区别4.强化学习的特点5.离散马尔可夫过程6.马尔可夫奖励过程7.马尔可夫决策过程8.策略学习8.1.策略学习概念8.2.策略评估与贝尔曼方程 9.强化学习的最优策略求解10.基于价值的强…

K8s基础1——发展起源、资源对象、集群架构

文章目录 一、发展起源二、资源对象2.1 集群类2.2 应用类2.3 存储类2.4 安全类 三、集群架构 一、发展起源 K8s官方文档 K8s怎么来的&#xff1f; 十几年来&#xff0c;谷歌内部使用的大规模集群管理系统是Brog&#xff0c;基于容器技术实现了资源管理的自动化和跨多个数据中心…

基于Python的连锁超市收银系统的开发与研究_kaic

基于Python的连锁超市收银系统的开发与研究 摘要&#xff1a;近几年来&#xff0c;国内的连锁超市收银系统也在不断的发展与完善&#xff0c;超市收银系统是一个超市管理的核心&#xff0c;他决定了超市的安全性。目前&#xff0c;大大小小的超市基本上由传统的人工管理逐渐过渡…

IT 面试手册 - 序

IT 面试手册 - 序 前言 首先&#xff0c;感谢你阅读我的文章。作为在计算机互联网行业摸爬滚打近十载的半个过来人&#xff0c;在这里分享一些关于求职面试和自我提升的心得感悟&#xff0c;希望能够给你一些启发。 背景 对于 IT 从业者来说&#xff0c;当今这个时代&#x…

Docker的四种网络模式

1.Host 模式 通常来讲&#xff0c;启动新的Docker容器&#xff0c;都会分配独立的Network Namespace隔离子系统&#xff0c;如果在运行是指定为host模式&#xff0c;那么Docker容器将不会获得一个独立的Network Namespace&#xff0c;而是和宿主机共用一个Network Namespace子…

计算机网络知识复习

目录 TCP/IP协议群做了哪些事情&#xff1f; TCP协议为什么是3次握手&#xff0c;4次挥手&#xff1f; 如果网络延迟是30ms&#xff0c;那么Ping(基于UDP的)一个网站需要多少ms&#xff1f; 如果请求一个HTTP协议的网站&#xff0c;TTFB至少ms&#xff1f; CDN更换图片&am…

WeakMap 与 WeakSet

WeakSet WeakSet 结构与 Set 类似&#xff0c;也是不重复的值的集合。 成员都是数组和类似数组的对象&#xff0c;WeakSet 的成员只能是对象&#xff0c;而不能是其他类型的值。 若调用 add() 方法时传入了非数组和类似数组的对象的参数&#xff0c;就会抛出错误。 const b …

Linux进程间通信 - 信号(signal) 与 管道(pipe) 与 消息队列

什么是进程间通信&#xff0c;就是进程与进程之间进行通信&#xff0c;互相发送消息&#xff1b;可以通过 信号 或者 管道 或者 消息队列 或者 信号量 去通信&#xff01; 目录 一、信号 1. 信号简介 2. 都有那些信号&#xff1f; 3. 注册信号的函数 1). signal 2). sig…

十一、通过六个因素对织物起球等级进行预测

一、需求分析 根据之前做训练的模型&#xff0c;对不同等级的标准样卡进行测试 测试样本有48张&#xff0c;其中包括起球个数、起球总面积、起球最大面积、起球平均面积、对比度、光学体积六个指标&#xff0c;最终确定出织物的等级 数据集fiber.csv大致结构如下&#xff1a; …

微服务保护 笔记分享【黑马笔记】

微服务保护 1.初识Sentinel 1.1.雪崩问题及解决方案 1.1.1.雪崩问题 微服务中&#xff0c;服务间调用关系错综复杂&#xff0c;一个微服务往往依赖于多个其它微服务。 如图&#xff0c;如果服务提供者I发生了故障&#xff0c;当前的应用的部分业务因为依赖于服务I&#xff…

Notion——构建个人知识库

前言 使用Notion快三年了&#xff0c;它All in one的理念在使用以后确实深有体会&#xff0c;一直想找一个契机将这个软件分享给大家&#xff0c;这款笔记软件在网上已经有很多的教程了&#xff0c;所以在这里我主要想分享框架这方面给大家&#xff0c;特别对于学生党、准研究生…

【Java笔试强训 12】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;二进制插…

深圳雷龙SD NAND的存储应用方案

前言: 很感谢深圳雷龙发展有限公司为博主提供的两片SD NAND的存储芯片&#xff0c;在这里博主记录一下自己的使用过程以及部分设计。 深入了解该产品&#xff1a; 拿到这个产品之后&#xff0c;我大致了解了下两款芯片的性能。CSNP4GCR01-AMW是一种基于NAND闪存和SD控制器的4G…

paddle 52 在paddleseg中实现cutmix数据增强方式

CutMix是一种极其有效的数据增强方式,尤其是在遥感影像语义分割中。这主要是因为遥感影像标注成本较大,在实际业务中通常都是采用局部标注的方式进行标注,如下图所示仅对标注成本较小的区域进行标注,而对标注成本较大的地方进行忽略。这使得标签数据中各种类别边界较少(例…

【Python零基础学习入门篇③】——第三节:Python的字符串类型

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

VS+Qt+C++银行排队叫号系统

程序示例精选 VSQtC银行排队叫号系统 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQtC银行排队叫号系统>>编写代码&#xff0c;带用户登录&#xff0c;管理员登录&#xff…

Mysql当中Json相关的函数详解

目录 一、前言二、创建JSON文本的函数2.1.JSON_ARRAY&#xff08;转换json数组&#xff09;2.2.JSON_OBJECT&#xff08;转换json对象&#xff09;2.3.JSON_QUOTE&#xff08;转义字符串&#xff09; 三、搜索JSON文本的函数3.1.JSON_CONTAINS&#xff08;json当中是否包含指定…