C++ 基础STL-list容器

news2025/1/21 22:12:33

STL-list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的。这意味着,list 容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中。

 

 链表的优点:可以对任意位置进行快速插入和删除

            缺点:遍历速度没有数组快,占用空间比数组大

list容器的迭代器(双向迭代器)

        List容器不能像vector一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。List迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取操作。

        所谓”list正确的递增,递减、取值、成员取用”是指,递增时指向下一个节点,递减时指向上一个节点,取值时取的是节点的数据值,成员取用时取的是节点的成员。

        由于list是一个双向链表,迭代器必须能够具备前移、后移的能力,所以list容器提供的是Bidirectional Iterators. List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效。这在vector是不成立的,因为vector的插入操作可能造成记忆体重新配置,导致原有的迭代器全部失效,甚至List元素的删除,也只有被删除的那个元素的迭代器失效,其他迭代器不受任何影响。 

需要注意的是:list容器不仅是一个双向链表,而且还是一个循环的双向链表

目录

list构造函数

list 赋值和交换

list 大小操作

list 插入和删除

 list 数据存取

list 反转和排序

总结:

list构造函数

list<T> lst;                      //list采用采用模板类实现,对象的默认构造形式:
list(beg,end);                    //构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);                     //构造函数将n个elem拷贝给本身。
list(const list &lst);            //拷贝构造函数。

示例:

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

void printList(const list<int>& L) {

	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	printList(L1);

	list<int>L2(L1.begin(), L1.end());
	printList(L2);

	list<int>L3(L2);
	printList(L3);

	list<int>L4(10, 1000);
	printList(L4);
}

int main() {

	test01();

	system("pause");

	return 0;
}

运行结果:

list 赋值和交换

assign(beg, end);                //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);                 //将n个elem拷贝赋值给本身。
list& operator=(const list &lst);//重载等号操作符
swap(lst);                       //将lst与本身的元素互换。

主要代码示例:

//赋值和交换
void test01()
{
	list<int>L1;
	L1.push_back(1);
	L1.push_back(2);
	L1.push_back(3);
	L1.push_back(4);
	printList(L1);

	//赋值
	list<int>L2;
	L2 = L1;
	printList(L2);

	list<int>L3;
	L3.assign(L2.begin(), L2.end());
	printList(L3);

	list<int>L4;
	L4.assign(10, 10);
	printList(L4);

}

//交换
void test02()
{

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

	list<int>L2;
	L2.assign(10, 100);

	cout << "交换前: " << endl;
	printList(L1);
	printList(L2);

	cout << endl;

	L1.swap(L2);

	cout << "交换后: " << endl;
	printList(L1);
	printList(L2);

}

运行结果:

list 大小操作

size();                 //返回容器中元素的个数

empty();                //判断容器是否为空

resize(num);            //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

  ​					    //如果容器变短,则末尾超出容器长度的元素被删除。

resize(num, elem);      //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

   			            //如果容器变短,则末尾超出容器长度的元素被删除。

示例主要代码:

void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	if (L1.empty())
	{
		cout << "L1为空" << endl;
	}
	else
	{
		cout << "L1不为空" << endl;
		cout << "L1的大小为: " << L1.size() << endl;
	}

	//重新指定大小
	L1.resize(10);
	printList(L1);

	L1.resize(2);
	printList(L1);
}

运行结果:

list 插入和删除

push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。

示例主要代码:

void test01()
{
	list<int> L;
	//尾插
	L.push_back(10);
	L.push_back(20);
	L.push_back(30);
	//头插
	L.push_front(100);
	L.push_front(200);
	L.push_front(300);

	printList(L);

	//尾删
	L.pop_back();
	printList(L);

	//头删
	L.pop_front();
	printList(L);

	//插入
	list<int>::iterator it = L.begin();
	L.insert(++it, 1000);
	printList(L);

	//删除
	it = L.begin();
	L.erase(++it);
	printList(L);

	//移除
	L.push_back(10000);
	L.push_back(10000);
	L.push_back(10000);
	printList(L);
	L.remove(10000);
	printList(L);

	//清空
	L.clear();
	printList(L);
}

运行结果:

 list 数据存取

front();        //返回第一个元素。
back();         //返回最后一个元素。

示例主要代码:

void test01()
{
	list<int>L1;
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	cout << "第一个元素为: " << L1.front() << endl;
	cout << "最后一个元素为: " << L1.back() << endl;

}

运行结果:

list 反转和排序

reverse();   //反转链表
sort();      //链表排序

示例主要代码:

void test01()
{
	list<int> L;
	L.push_back(2);
	L.push_back(1);
	L.push_back(3);
	L.push_back(5);
	printList(L);

	//反转容器的元素
	L.reverse();
	printList(L);

	//排序
	L.sort(); //默认的排序规则 从小到大
	printList(L);

	L.sort(myCompare); //指定规则,从大到小
	printList(L);
}

运行结果:

总结:

1.list 是 STL 中的一个序列容器,实现的是双向链表,每个元素都有两个指针,分别指向元素的前驱和后继。

2.list 不需要指定内存大小,因为他存储在不连续的内存空间中,并由指针将他们连接在一起。

3.由于链表的特点,不能进行内部的随机访问,无法通过位置来访问元素,即不支持[ ] 操作符和vector.at() 操作,必须逐个遍历,可以通过开始元素或者最后一个元素遍历,它的查找要在O(n)的时间才能完成。但它允许序列快速在任意位置进行插入和删除操作作,包括在两边的pop()和push()操作。
 

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

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

相关文章

【触觉智能分享】RK3568+Debian系统如何旋转屏幕显示方向

大家在购买开发板后&#xff0c;默认开机进入桌面屏幕显示方向是竖屏&#xff0c;有些用户想修改为横屏显示&#xff0c;本文就用IDO-EVB3568为例&#xff0c;用Debian系统演示如何旋转屏幕显示方向&#xff0c;此方法适用于所有RK356X系列产品。 IDO-EVB3568开发板拥有四核A5…

【数据结构】--- 几分钟走进栈和队列(详解-上)

文章目录 前言&#x1f31f;一、栈&#x1f30f;1.1栈的概念及结构&#xff1a;&#x1f30f;1.2实现栈的两种方式&#xff1a; &#x1f31f;二、栈实现(数组栈)&#x1f30f;2.1结构&#xff1a;&#x1f30f;2.2初始化&#xff1a;&#x1f4ab;2.2.1第一种代码&#xff1a;…

Direct3D 12——纹理——纹理贴图的作用

法线贴图 在不增加三角形的情况下增加表面细节 任何一个像素它的法线都做一个扰动&#xff0c;通过定义不同的高度和临近位置的高度差重新计算法线 纹理定义的是任何一个点&#xff0c;它的相对的高度的移动&#xff0c;通过高度的变化改变法线 原曲面法向量n ( p) (0,1) p点…

代码随想录 LeetCode链表篇 Java

文章目录 &#xff08;简单&#xff09;203. 移除链表元素&#xff08;中等&#xff09;707. 设计链表&#xff08;简单&#xff09;206. 反转链表&#xff08;中等&#xff09;24. 两两交换链表中的节点&#xff08;中等&#xff09;19. 删除链表的倒数第 N 个结点&#xff08…

Schlumberger ECLIPSE CRACK

Schlumberger ECLIPSE CRACK 工业和工程软件旨在模拟Schlumberger ECLIPSE Simulation的碳氢化合物&#xff0c;该模拟与Shelberger的技术服务有关&#xff0c;以及用于预测和历史的容器中当前方程数量的最新和最新解决方案集。动态行为是各种传统和不寻常的石油和天然气模式。…

DevExpress:报表控件绑定数据库数据源的三种方式(Winform)

1.写在前面 如果你是和我一样&#xff0c;第一次接触DevExpress&#xff0c;并且因为网上资源眼花缭乱无从下手&#xff0c;然后脑子一转直接到DevExpress官网寻找官方使用文档的&#xff0c;那我们的了解顺序应该差不多是一致的。 DevExpress官网&#xff1a;https://www.de…

【笔试强训选择题】Day12.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…

Facebook 手机应用广告:在移动时代实现营销突破

在移动时代&#xff0c;手机已经成为人们生活的重要组成部分。随着移动互联网的普及&#xff0c;人们更频繁地使用手机来浏览社交媒体、获取信息和进行购物。 对于企业而言&#xff0c;如何在移动平台上实现营销突破&#xff0c;吸引用户的注意力和提升品牌价值&#xff0c;是…

数说热点|社恐人群运动健身指南:不想去健身房,那就在家找面墙

连杰伦都开始跳操了&#xff0c;你还不动动动动动起来&#xff1f; 随着《运动者联盟》这档体育挑战真人秀节目的完美收官&#xff0c;忙碌生活中的运动激情似乎又被点燃了。5月9日&#xff0c;周杰伦现身厦门&#xff0c;在活动现场和刘耕宏合体跳起了《本草纲目》&#xff0…

音视频技术开发周刊 | 293

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 谷歌全面反攻 ChatGPT&#xff01;PaLM 2、Gemini 双杀&#xff0c;Bard 正式开放 以上是2023 Google I/O 大会的重点内容&#xff0c;AI含量极高。 谷歌推拥有26000个H10…

uni-app框架的小程序开发环境

文章目录 一、下载微信开发工具安装 二、构建uni-app开发环境2.1 Node.js下载与安装2.2 下载HBuilder-X2.3 创建uni-app项目2.4 填入uni-app专属标识和小程序标识 在阅读此博文前&#xff0c;需要注册完毕小程序账号 一、下载微信开发工具 微信开发工具下载地址 下载稳定版即…

代码随想录算法训练营day41 | 343. 整数拆分,96.不同的二叉搜索树

代码随想录算法训练营day41 | 343. 整数拆分&#xff0c;96.不同的二叉搜索树 343. 整数拆分解法一&#xff1a;动态规划 96.不同的二叉搜索树解法一&#xff1a;动态规划 总结 343. 整数拆分 教程视频&#xff1a;https://www.bilibili.com/video/BV1Mg411q7YJ 1、dp[i]代表…

【Linux命令】脚本里常用的几个命令sort,uniq,tr,cut,split,eval

脚本里常用的命令 一、SORT命令1.1、语法格式1.2常用选项 二、uniq命令2.1命令格式2.2常用选项2.3小实验&#xff0c;过滤出现三次以上的IP地址 三、tr命令3.1语法格式3.2常用选项3.3实验 四、cut命令4.1语法格式4.2常用选项 五、split命令5.1语法格式5.2常用选项 六、eval七、…

一个优秀系统构架师应具备的能力

作为软件开发的设计架构师&#xff0c;那么必须拥有一定的编程技能&#xff0c;同时有高超的学习新的架构设计、程序设计技能。另外&#xff0c;我觉得作为软件架构师&#xff0c;还必须了解一定的硬件、网络、服务器的基本知识。要不然&#xff0c;你都不知道有些什么材料可以…

基于MWORKS的电动汽车电平衡分析

1 引言 随着电动汽车的快速发展、电池技术的进步和智能电力管理系统的应用&#xff0c;电动汽车电平衡已经成为了电动汽车技术研究中的重要问题之一。 电动汽车电平衡是指车辆发电机、蓄电池、整车用电器在一定时间内的电能供给与消耗达到平衡状态。如果车辆电能产生与消耗无法…

USART硬件流控制概念以及原理(硬件控制流以及软件控制流)

USART 数据流控制 也就是 USART_HardwareFlowControl 一、流控制的作用 这里讲到的 “流”&#xff0c;指的是数据流&#xff1b;在数据通信中&#xff0c;流控制是管理两个节点之间数据传输速率的过程&#xff0c;以防止出现接收端的数据缓冲区已满&#xff0c;而发送端依然…

ResNet 论文理解含视频

ResNet 论文理解 论文理解 ResNet 网络的论文名字是《Deep Residual Learning for Image Recognition》&#xff0c;发表在2016年的 CVPR 上&#xff0c;获得了 最佳论文奖。ResNet 中的 Res 也是 Residual 的缩写&#xff0c;它的用意在于基于 残差 学习&#xff0c;让神经网…

真实业务场景使用-门面模式(外观)设计模式

1.前言 最近接到要修改的业务功能&#xff0c;这个业务增删改查很多功能都需要校验时间&#xff0c;比如&#xff1a; 1.失效时间不能超过自己父表的失效时间&#xff0c; 2.失效时间不能是当前时间 3.失效时间不能早于生效时间 类似这样的不同的判断还有很多&#xff0c;…

软考A计划-真题-分类精讲汇总-第十章(程序设计语言)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

【GO 编程语言】切片与Map

切片与Map 文章目录 切片与Map一、切片 Slice1.定义切片2.make 函数创建切片3.切片扩容与遍历4.在已有数组上创建切片5.切片是引用类型7.深拷贝、浅拷贝 二、Map1.Map 初始化2.map 的使用3.map 的遍历4.map 结合 slice 一、切片 Slice 1.定义切片 Go 语言切片是对数组的抽象。…