【C++】 STL库list容器

2023-10-27


  1. 头文件:#include

  2. Lists将元素按顺序储存在链表中。与 向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。

  3. list的特点:

    (1)不使用连续的内存空间这样可以随意地进行动态操作;
    (2)可以在内部任何位置快速地插入或删除,当然也可以在两端进行push和pop。
    (3)不能进行内部的随机访问,即不支持[ ] 操作符和vector.at()
    (4)相对于verctor占用更多的内存。

1、 list中的构造函数

  1. list() 声明一个空列表;
  2. list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的,元素默认值为:0,即n个0
  3. list(n,val) 声明一个由n个val元素的列表;
  4. list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素;
  5. list (const list &);拷贝构造函数,要求类型一致;
  1. list data4(data3.begin(),data3.end()); √
    list data4(data3.begin(),data3.begin()+3); ×
    报错:没有“+”运算符重载
  2. for (; itor4 != data4.end()-8; ++itor4) { // 报错:没有“-”运算符重载
    cout << *itor4 << " ";
    }

for (; itor4 != data4.end(); ++itor4) {
cout << *itor4 << " "; // k k k k k k
}

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

int main() {
	//------------------ 1. list() 声明一个空列表
	list<int> data1;
	cout << data1.size() << endl; // 0


	 //------------------ 2.   list(n) 声明一个有n个元素的列表.值为0
	list<int> data(10);

	list<int>::iterator itor = data.begin();   // 遍历
	for (; itor != data.end(); ++itor) {
		cout << *itor << " ";	// 0 0 0 0 0 0 0 0 0 0  
	}

	//------------------3. list(n, val) 
	list<int> data2(5, 10);

	list<int>::iterator itor2 = data2.begin();   // 遍历
	for (; itor2 != data2.end(); ++itor2) {
		cout << *itor2 << " ";	// 10 10 10 10 10 
	}


	//------------------4. list(first, last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素
	list<char> data3(6,'k');
	list<char> data4(data3.begin(),data3.end());

	list<char>::iterator itor4 = data4.begin();   // 遍历
	for (; itor4 != data4.end(); ++itor4) {
		cout << *itor4 << " ";	// k k k k k k 
	}


	//------------------5. list(const list &); 拷贝构造函数
	list<char> data5(6, 'g');
	list<char> data6(data5);

	list<char>::iterator itor6 = data6.begin();   // 遍历
	for (; itor6 != data6.end(); ++itor6) {
		cout << *itor6 << " ";	// g g g g g g
	}

	return 0;
}

2、 begin()和end()——list 容器的iterator

  1. 通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator
  2. 可以调用list容器的end()函数来得到list末端下一位置,相当于:int a[n]中的第n+1个位置a[n],实际上是不存在的,不能访问,经常作为循环结束判断结束条件使用。

3、 增

3.1 push_back() 末端插入

3.2 push_front() 头部插入

3.3 insert() 在指定位置插入n个元素

  1. l1.insert(l1.begin(),100); // 在l1的开始位置插入100。
  2. l1.insert(l1.begin(),2,200); // 在l1的开始位置插入2个100。
  3. l1.insert(l1.begin(),l2.begin(),l2.end()); // 在l1的开始位置插入l2的从开始到结束的所有位置的元素。

代码演示

int main() {
	//------------------ insert() 在指定位置插入n个元素
	list<int> data1;
	data1.push_back(1);
	data1.push_back(1);
	data1.push_back(1);

	data1.push_front(2);
	data1.push_front(2);
	data1.push_front(2);

	list<int>::iterator itor1 = data1.begin();   // 遍历
	for (; itor1 != data1.end(); ++itor1) {
		cout << *itor1 << " ";	// 2 2 2 1 1 1
	}

	//******** 1.在某个位置插入1个x
	data1.insert(data1.begin(), 9);
	data1.insert(data1.begin(), 10);
	list<int>::iterator itor2 = data1.begin();   // 遍历
	for (; itor2 != data1.end(); ++itor2) {
		cout << *itor2 << " ";	// 10 9 2 2 2 1 1 1
	}

	//******** 2.在某个位置插入n个x
	list<int> data2;
	data2.push_back(1);
	data2.push_back(1);
	data2.push_back(1);

	data2.insert(data2.begin(), 5, 4); // 头插
	data2.insert(data2.begin(), 2, 7);

	data2.insert(data2.end(), 5, 4);  // 尾插
	data2.insert(data2.end(), 2, 7);
	
	for (list<int>::iterator itor3 = data2.begin(); itor3 != data2.end(); ++itor3) {   // 遍历
		cout << *itor3 << " ";	//  7 7 4 4 4 4 4 1 1 1 4 4 4 4 4 7 7
	}


	//******** 3.在某个位置插入[begin,end)元素
	list<int> data3;
	data3.push_back(1);
	data3.push_back(1);
	data3.push_back(1);

	list<int> data4;
	data4.push_back(2);
	data4.push_back(2);
	data4.push_back(2);
	cout << endl;

	data3.insert(data3.begin(), data4.begin(),data4.end()); // 头插
	for (auto itor3 = data3.begin(); itor3 != data3.end(); ++itor3) {   // 遍历
		cout << *itor3 << " ";	// 2 2 2 1 1 1
	}

	return 0;
}

4、删

  1. 通过pop_back()删除最后一个元素,通过pop_front()删除第一个元素;
  2. 序列必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。

4.1 pop_back() 删尾

4.2 pop_front() 删头

4.3 erase() 删除n个元素

  1. l1.erase(l1.begin()); 将l1的第一个元素删除。
  2. l1.erase(l1.begin(),l1.end()); 将l1的从begin()到end()之间的元素删除。

【注意】:
data2.end() 表示指向4后面的位置,该位置不存在元素,因此:
auto itor2 = data2.erase(–data2.end()); ✔ 删除的是4,剩下为 2 3
auto itor2 = data2.erase(data2.end()); ❌ 删除的元素不存在,报错

4.4 clear() 清空

代码演示

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

int main() {
	//------------------  pop_back 删尾和 pop_front() 删头
	list<int> data1;
	data1.push_back(1);
	data1.push_back(2);
	data1.push_back(3);

	data1.pop_back(); // 删尾
	for (auto it = data1.begin(); it != data1.end(); ++it) {
		cout << *it << " "; // 1 2
	}

	data1.pop_front(); // 删头
	for (auto it = data1.begin(); it != data1.end(); ++it) {
		cout << *it << " "; // 2
	}
	

	//------------------ erase() 删除n个元素

	// ******* 1. erase(iterator it)
	list<int> data2;
	data2.push_back(1);
	data2.push_back(2);
	data2.push_back(3);
	data2.push_back(4);
	
	//==== 1.1 erase(data2.begin())
	auto itor1= data2.erase(data2.begin());
	cout <<"删除后的下一个元素为:"<< *itor1 << endl; // 2
	
	for (auto it = data2.begin(); it != data2.end(); ++it) {
		cout << *it << "  "; // 2  3  4
	}
	

	//==== 1.2 erase(--data2.end())
	
	/*原列表元素:2 3 4;
	data2.end() 表示指向4后面的位置,该位置不存在元素,因此:
	auto itor2 = data2.erase(--data2.end());  ✔删除的是4,剩下为 2  3 
	auto itor2 = data2.erase(data2.end()); ❌ 删除的元素不存在,报错 */
	
	auto itor2 = data2.erase(--data2.end());
	for (auto it = data2.begin(); it != data2.end(); ++it) {
		cout << *it << "  "; // 2  3 
	}
	


	// ******* 2. erase(iterator first,iterator last);删除当前列表[first,last)之间的元素
	list<int> data3;
	data3.push_back(1);
	data3.push_back(2);
	data3.push_back(3);
	data3.push_back(4);

	auto it3 = data3.erase(++data3.begin(), --data3.end());
	for (auto it = data3.begin(); it != data3.end(); ++it) {
		cout << *it << "  "; // 1  4 
	}


	//------------------ clear()  清空
	list<int> data4;
	data4.push_back(1);
	data4.push_back(2);
	data4.push_back(3);
	data4.push_back(4);

	data4.clear();
	for (auto it = data4.begin(); it != data4.end(); ++it) {
		cout << "data4="<< *it << "  "; //   (空)
	}


	return 0;
}

5、改

5.1 assign() 替换/赋值

  1. l1.assign(n,val); // 将当前列表中所有元素替换为n个T类型的val
  2. l1.assign(l2.begin(),l2.end()); // 将12列表中的从l2.begin()到l2.end()之间的数值赋值给当前列表l1

5.2 swap() 交换

交换两个链表(两个重载)语法:(都可能完成连个链表的交换)
(1) l1.swap(l2);
(2)swap(l1,l2);

5.3 reverse() 逆置

5.4 merge() 合并

合并两个链表并使之默认升序(也可改):
l1.merge(l2,greater());

  1. 调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。
  2. 其实默认是升序,greater()可以省略。
  3. 另外greater()是可以变的,也可以不按升序排列,例如:less()是降序排列。

代码演示

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

int main() {
	//------------------ 1. assign() 赋值/替换 
	// ***** 1.1 assign(n,val) 将列表中所有元素替换为n个T类型的val
	list<int> data1;
	data1.push_back(1);
	data1.push_back(2);
	data1.push_back(3);

	data1.assign(2, 9);
	for (auto it = data1.begin(); it != data1.end(); ++it) {
		cout << "data1="<< *it << " "; // data1=9 data1=9
	}
	
	// ***** 1.2 l1.assign(l2.begin(), l2.end());  将12列表中的从l2.begin()到l2.end()之间的数值赋值给当前列表l1
	list<int> data1_2;
	data1_2.push_back(1);
	data1_2.push_back(1);
	data1_2.push_back(1);

	list<int> data1_3;
	data1_3.push_back(2);
	data1_3.push_back(2);
	data1_3.push_back(2);

	data1_2.assign(++data1_3.begin(), data1_3.end());
	for (auto it = data1_2.begin(); it != data1_2.end(); ++it) {
		cout << "data1_2 = " << *it << " "; // data1_2 = 2 data1_2 = 2
	}


	//------------------ 2. swap() 交换
	// ***** 2.1  l1.swap(l2); 
	list<int> data2_1;
	data2_1.push_back(1);
	data2_1.push_back(1);
	data2_1.push_back(1);

	list<int> data2_2;
	data2_2.push_back(2);
	data2_2.push_back(2);
	data2_2.push_back(2);

	data2_1.swap(data2_2); // 交换

	for (auto it = data2_1.begin(); it != data2_1.end(); ++it) {
		cout << "data2_1 = " << *it << " "; // ata2_1 = 2 data2_1 = 2 data2_1 = 2
	}

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

	//***** 2.2  swap(l1,l2);
	swap(data2_1, data2_2);
	for (auto it = data2_1.begin(); it != data2_1.end(); ++it) {
		cout << "data2_1 = " << *it << " "; // data2_1 = 1 data2_1 = 1 data2_1 = 1
	}
	cout << endl;
	for (auto it = data2_2.begin(); it != data2_2.end(); ++it) {
		cout << "data2_2 = " << *it << " "; // data2_2 = 2 data2_2 = 2 data2_2 = 2
	}


	//------------------ 3. reverse() 逆置
	list<int> data3;
	data3.push_back(1);
	data3.push_back(2);
	data3.push_back(3);

	data3.reverse();
	for (auto it = data3.begin(); it != data3.end(); ++it) {
		cout <<  *it << " "; // 3 2 1
	}


	//------------------ 4. merge() 合并

	//**** 合并后降序排列

	//**** 合并后升序排列



	return 0;
}

6、查

6.1 front() 获取头部元素

  1. 通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。
  2. 但是有一点要注意,就是list中元素是空的时候,这时候调用front()和back()会发生什么呢?实际上会发生不能正常读取数据的情况,但是这并不报错,那我们编程序时就要注意了,个人觉得在使用之前最好先调用empty()函数判断list是否为空。

6.2 back() 获取尾部元素

6.3 遍历(不支持 [] 和“<<”)

int main() {
	//------------------1. front() 获取头部元素 和 back() 获取尾部元素
	list<char> data1 = {'a','b','c'};
	cout << data1.front()<<endl; // a
	cout<< data1.back() << endl; // c

	// -----------------2. 遍历
	//******* 法1:
	list<char>::iterator itor;
	for (itor = data1.begin(); itor != data1.end(); ++itor) {
		cout << *itor << " "; // a b c
	}

	//******* 法2:
	for (list<char>::iterator itor = data1.begin(); itor != data1.end(); ++itor) {
		cout << *itor << " "; // a b c
	}

	//******* 法3:
	for (auto it = data1.begin(); it != data1.end(); ++it) {
		cout << *it << " ";
	}

	return 0;
}

7、empty() 判空

8、resize() 修改list容器容量

  1. resize(n)将list的长度改为n;

(1)超出的元素将被删除;
(2)不足部分:

① 类型 默认补‘空格’
② 类型 默认补0

  1. resize(n,val),将list的长度改为n;
    (1)超出的元素将被删除;
    (2)不足部分:补val
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】 STL库list容器 的相关文章

随机推荐

  • 虚拟机与主机串口通信(主机与主机)

    简介 由于某些主机无串口接口 或者需要两台主机交互通信来实现串口收发端的调试 modubus通讯的调试 为方便起见 查阅资料后 特有此文 一 环境 硬件 x86 系统 本机 win7 64 Vmware ubuntu16 04 软件 Vir
  • 微信小程序学习笔记--商城案例(黑马教程)

    目录 起步 运行于小程序 Git 托管到码云 tabbar 创建tabBar 配置tabbar 导航条颜色 首页 网络配置 请求轮播图数据 渲染轮播图 配置小程序分包 点击轮播图 跳转详情页 全局添加弹窗方法 获取分类导航数据 渲染分类导航
  • numpy的文件存储 .npy .npz 文件

    将数组以二进制格式保存到磁盘 转自 https blog csdn net m0 37041325 article details 78006203 np load和np save是读写磁盘数组数据的两个主要函数 默认情况下 数组是以未压缩
  • 最近写了10篇Java技术博客【SQL和画图组件】

    1 Java获取SQL语句中的表名 2 Java SQL 解析器实践 3 Java SQL 格式化实践 4 Java 画图 画图组件jgraphx项目整体介绍 一 画图组件jgraphx项目导出实践 二 画图组件jgraphx项目连接线实践
  • 小程序开发:在登录时弹窗用户使用协议

    本次讲的是如何在用户打开小程序时候弹窗该小程序的使用协议 阅读确认后方可继续使用小程序 这一点的意义在于 目前小程序对于各个开放接口的使用限制更严格 使用开放接口获取用户信息需要添加使用的用途说明 那我们正好可以使用这一个使用协议弹窗来说明
  • K8s:二进制部署高可用K8s集群

    K8s二进制高可用部署 说在前面 本章相关代码及笔记地址 飞机票 Github Java超神之路 Java全生态技术学习笔记 一起超神吧 CSDN Java超神之路 Java全生态技术学习笔记 一起超神吧 前言 本文所有涉及软件包等文件均在
  • 禅道——安装教程

    禅道安装指南 前言 一 禅道的安装和配置 1 1 其他修改 前言 禅道 项目管理工具 管理软件开发的整个流程 一 禅道的安装和配置 安装 点这里 进入官网 点击下载 点进去之后选择自己相要的版本 这里只要不是最新版本都会稳定
  • Multisim实现555计时器模拟简易电子琴

    555计时器模拟简易电子琴 一 元器件介绍 二 原理分析 三 仿真实验 四 仿真错误 一 元器件介绍 这里用到的元器件有 DIgital power VCC 数字电源 频率计数器 XFC 示波器 XSC ground 数字地 Capacit
  • cmake建立自己的package

    通过cmake建立自己的package cmake提供了CMakePackageConfigHelpers来方便实现我们的需求 详细文章参考如下 1 https blog csdn net xiaoxiaozengz article det
  • go协程、管道

    请感受一下协程的强大 使用了管道序列 package main import fmt time 创建一个管道 用于写入数据 func writeChantest writeChan chan int for i 0 i lt 20 i wr
  • ISO 26262:保障驾驶安全的汽车功能安全标准

    来源 中豪认证 随着汽车科技的迅猛发展 越来越多的电子系统和功能被引入汽车中 为驾驶体验和安全性带来了巨大的改进 然而 这些复杂的电子系统也带来了潜在的风险和安全挑战 为了确保现代汽车在各种情况下的安全性 国际标准化组织于2011年发布了I
  • 实现浏览页面时校验用户是否已经完成登录的功能

    一 实现原理 实现步骤 1 创建自定义过滤器LoginWebFilter java 2 在启动类上加入注解 ServletComponentScan 用来扫描web相关的注解 3 完善过滤器的处理逻辑 二 代码实现 首先在main java
  • 关于Xilinx下载器驱动安装及常见问题解决方法

    PC操作系统平台 Win7x64 ISE14 4 ISE14 7 下载器工作状态指示灯说明 如果Xilinx的下载器与电脑连接之后 下载器上面的指示灯不亮 说明PC上安装的下载器驱动有问题或者是下载器坏掉了 如果下载器与电脑连接之后 并与开
  • CTFshow 每日一练

    一 web签到题 打开链接 查看源码 利用base64解码得到flag 二 web2 看到有提示 SQL注入 先试着使用万能密码登陆 发现有回显 直接sql注入 or 1 1 order by 3 发现到4时不回显 开始爆库名 看看哪个位置
  • 2、ubuntu18.04安装cmake

    本文以安装cmake3 18 0为例 1 获取安装包 wget https cmake org files v3 18 cmake 3 18 0 Linux x86 64 tar gz 2 解压压缩包 tar zxvf cmake 3 18
  • GD32F3x0 USB CDC应用案例

    GD32F3x0 USB CDC应用 本文有点长 描述了从0开始移植驱动到应用的过程和思路 准备工作 因项目需求这两天需要做个USB的虚拟COM口发卡器 实现双向通讯 由于功能较为简单我们选择GD32F350来开发 先跑跑官方例程 GD32
  • 分享程序员在囧途网站

    不知不觉的在博客园看到了失业的程序员系列文章 我就带着好奇的看了几章 然后发现类似创业的文章的经历的文章 都是程序员爱看到的文章 同时把这样的经历加上一点修饰 是很多程序员喜欢的话题 也是程序员想看到的文章 不知道不觉到了第六章的时候 文章
  • LayUI数据表格 通用工具栏 分页+搜索+排序

    完成效果 1 接收和展示后端接口传来的数据 2 分页和跳页 设置每页的数量 3 工具栏 查看 修改 删除 4 工具栏 筛选列 导出Excel 打印 5 搜索功能 6 后端排序功能 本实例只展示了实现功能的必须代码 后端代码的非必须部分未贴出
  • 第十三届蓝桥杯 ——刷题统计

    题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛 他计划周一至周五每天做 a a a 道题目 周六和周日每天做 b b b 道题目 请你帮小明计算 按照计划他将在第几天实现做题数大于等于
  • 【C++】 STL库list容器

    STL库list容器 1 list中的构造函数 2 begin 和end list 容器的iterator 3 增 3 1 push back 末端插入 3 2 push front 头部插入 3 3 insert 在指定位置插入n个元素