C++ list 的使用

目录

1. 构造函数

1.1 list ()

1.2 list (size_t n, const T& val = T())

1.3 list (InputIterator first, InputIterator last)

2. bool empty() const

3.  size_type size() const

4. T& front()

 4. T& back()

5. void push_front (const T& val)

6. void pop_front()

7. void push_back (const T& val)

8. void pop_back()

9. 迭代器

10. iterator insert (iterator pos, const T& val)

11.  void insert (iterator pos, size_t n, const T& val)

12. iterator erase (iterator pos)

13. void swap (list& x)

14. void resize (size_t n, const T& val = T())

15.  void clear()

16. 下面的这些函数都很好理解 

16.1 void remove (const T& val)

16.2 void unique()

16.2 void merge(list& x)

16.3 void sort()

16.4 void reverse()


list 的介绍,来源:list - C++ Reference (cplusplus.com)

1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。

3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。

4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率 更好。

5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这 可能是一个重要的因素)

1. 构造函数

1.1 list ()

这里的 T 是模板参数,list 可以存储任意类型的数据嘛。

通过 list 的简介,我们知道 list 的底层其实是一个带头双向循环链表 (以下简称双链表),在定义 list 的时候,我们需要初始化一个哨兵位的头结点。哨兵位的头结点不存储有效数据。无参构造就是用来初始化哨兵位的头结点的!

1.2 list (size_t n, const T& val = T())

这个构造函数可以初始化一个长度为 n 的,值均为 val 的双链表。

#include<iostream>
#include<list>

using namespace std;

int main()
{
	list<int> lt(5, 8);
	//输出:8 8 8 8 8
	for (auto e : lt)
		cout << e << " ";
	cout << endl;
}

1.3 list (InputIterator first, InputIterator last)

这个构造函数可以用一段迭代器区间来初始化双链表。构造的区间:[first, last)。

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

int main()
{
	vector<int> arr;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);

	list<int> lt(arr.begin(), arr.end());
	//输出:1 2 3 4 5
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

2. bool empty() const

判断一个链表是不是空链表!如果有有效数据,返回 true,反之返回 false。

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

int main()
{
	list<int> lt1;
	cout << lt1.empty() << endl; //输出:1

	list<int> lt2(5, 8);
	cout << lt2.empty() << endl; //输出:0

	return 0;
}

3.  size_type size() const

这个函数可以获取双链表的长度。

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

int main()
{
	list<int> lt2(5, 8);
	cout << lt2.size() << endl; //输出:5

	return 0;
}

4. T& front()

这个函数可以获取双链表的第一个有效元素。有 const 和非 const 两个版本,支持普通对象和 const 对象的调用。

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

int main()
{
	vector<int> arr;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);

	list<int> lt(arr.begin(), arr.end());

	cout << lt.front() << endl; //输出:1

	return 0;
}

 4. T& back()

这个函数可以获取双链表的最后一个有效元素。有 const 和非 const 两个版本,支持普通对象和 const 对象的调用。

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

int main()
{
	vector<int> arr;
	arr.push_back(1);
	arr.push_back(2);
	arr.push_back(3);
	arr.push_back(4);
	arr.push_back(5);

	list<int> lt(arr.begin(), arr.end());

	cout << lt.back() << endl; //输出:5

	return 0;
}

5. void push_front (const T& val)

双链表头插元素。因为之前我们都用 C 语言实现过双链表,学习 list 的使用就非常简单啦!

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

int main()
{
	list<int> lt;

	lt.push_front(4);
	lt.push_front(3);
	lt.push_front(2);
	lt.push_front(1);

	//输出:1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

6. void pop_front()

双链表头删元素。

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

int main()
{
	list<int> lt;

	lt.push_front(4);
	lt.push_front(3);
	lt.push_front(2);
	lt.push_front(1);

	//输出:1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

    lt.pop_front();
    
	//输出:2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

7. void push_back (const T& val)

双链表尾插元素。

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

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//输出:1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

8. void pop_back()

双链表尾删元素。

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

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//输出:1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

    lt.pop_back();

	//输出:1 2 3
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

9. 迭代器

list 的迭代器就不是简单的原生指针了。因为他的物理空间并不连续,因此 list 的迭代器需要进行封装,使得迭代器解引用能够返回节点存储的数据,使得迭代器加加,指向下一个节点,等等。具体的操作到我们模拟实现 list 的时候再说。

下面的图是 list 迭代器 begin() 与 end() 迭代器对应的双链表节点。

10. iterator insert (iterator pos, const T& val)

这个函数可以在 list 的 pos 位置处,插入一个值为 val 的元素。返回值就是返回新插入的元素的位置对应的迭代器。

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

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//在begin() 的位置插入 0 ,相当于头插
	lt.insert(lt.begin(), 0);

	//输出:0 1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	//在end() 的位置插入 5 ,相当于尾插
	auto it = lt.insert(lt.end(), 5);

	cout << *it << endl; //输出:5


	//输出:0 1 2 3 4 5
	for (auto e : lt)
		cout << e << " ";
	cout << endl;


	return 0;
}

11.  void insert (iterator pos, size_t n, const T& val)

这个函数可以在 pos 位置插入 n 个值为 val 的节点。

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

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//在begin() 的 位置插入 3 个值为 0 的节点
	lt.insert(lt.begin(), 3, 0);

	//输出:0 0 0 1 2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

12. iterator erase (iterator pos)

这个函数可以删除 pos 位置的双链表节点。不可以删除 end() 位置的节点,会报错的!VS2022 做了检查的。

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

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//相当于头删
	lt.erase(lt.begin());

	//输出:2 3 4
	for (auto e : lt)
		cout << e << " ";
	cout << endl;

	return 0;
}

13. void swap (list<T>& x)

这个函数可以交换两个链表。我们实现 list 的时候,list 类中维护的是哨兵位的头结点的指针,交换两个链表的指针就能实现这样的效果。仅限于我们自己实现的 list 类哈!list 实现方式多种多样!

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

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

	list<int> lt2;
	lt2.push_back(5);
	lt2.push_back(6);
	lt2.push_back(7);
	lt2.push_back(8);

	lt1.swap(lt2);

	//输出:5 6 7 8
	for (auto e : lt1)
		cout << e << " ";
	cout << endl;

	//输出:1 2 3 4
	for (auto e : lt2)
		cout << e << " ";
	cout << endl;


	return 0;
}

14. void resize (size_t n, const T& val = T())

stl 库的接口风格都很相似,list 的resize 和 vector,string 的 resize 简直一毛一样。当 n 小于双链表的长度,直接截断,当 n 大于双链表的长度,会用 val 区初始化新插入的节点。

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

int main()
{
	list<int> lt;

	lt.push_back(0);
	
	lt.resize(5, 1);

	//输出: 0 1 1 1 1
	for (auto e : lt)
		cout << e << " ";
	cout << endl;


	return 0;
}

15.  void clear()

清空链表,即释放所有链表节点。

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

int main()
{
	list<int> lt;

	lt.push_back(0);
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	lt.clear();

    //没有输出
	for (auto e : lt)
		cout << e << " ";
	cout << endl;


	return 0;
}

16. 下面的这些函数都很好理解 

16.1 void remove (const T& val)

移除链表中所有值为 val 的节点。

1 2 3 3 4 5 remove(3) :1 2 4 5。

16.2 void unique()

删除链表中重复的节点。

1 2 2 3 3 4 5 1 remove(3) :1 2 3 4 5 1。

这个函数只能对相邻的重复的数去重。因此多用于已经排好序的 list。

16.2 void merge(list<T>& x)

这个函数用于两个 list 的合并,前提是两个 list 都被排好序了!

例如:

list1:-1 2 3 5 8

list2:0 1 2 4 6 7

合并后的结果:-1 0 1 2 2 3 4 5 6 7 8。

16.3 void sort()

链表的排序。

16.4 void reverse()

链表的逆置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch核心技术与实战-05-elasticsearch的安装与简单配置-Windows

首先下载elasticsearch的zip包&#xff1a;下载地址 网络不通的解决方法&#xff1a;国内镜像站 es、kibana、logstash均可在华为云开元镜像站自行选择版本下载&#xff1a;下载地址 下载插件包&#xff1a; .\bin\elasticsearch-plugin install analysis-icu .\bin\elasti…

pgbackrest归档目录满,清理后写入仍报错,分析及处理

一、 背景 pgbackrest配置的归档目录/backup被写满 归档报错 No space left on device&#xff0c;wal日志堆积 解决方法直接查看第三部分 二、 问题分析及处理 1. 目录清理 首先想到的就是清理/backup目录&#xff0c;清理后剩余6T空间 但发现pgbackrest归档依旧在报错 No …

dc-5 靶机

1.扫描ip地址 2.网页 3.dirb 爆破目录 没有用 4.爆破端口 没有用 5. 文件上传漏洞 上传点 写一句话木马 蚁剑连接 1.shell反弹 蚁剑反弹 提权 使用命令 命令"find / -perm -us -type f 2>/dev/null"在整个文件系统 ("/") 中搜索设置了SUID权…

基于白鲸优化算法BWO优化的VMD-KELM光伏发电短期功率预测MATLAB代码(含详细算法介绍)

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; VMD适用于处理非线性和非平稳信号&#xff0c;例如振动信号、生物信号、地震信号、图像信号等。它在信号处理、振动分析、图像处理等领域有广泛的应用&#xff0c;特别是在提取信号中的隐含信息和去除噪声方面…

Capacitor 打包 h5 到 Android 应用,uniapp https http net::ERR_CLEARTEXT_NOT_PERMITTED

Capacitor 打包 h5 到 Android 应用&#xff0c;uniapp https http net::ERR_CLEARTEXT_NOT_PERMITTED capacitor 官网&#xff1a; https://capacitorjs.com/docs/ 项目上需要做一个 app&#xff0c;而这个 app 是用 uniapp 做的&#xff0c;里面用到了一个依赖 dom 的库&…

【Mysql】数据库三大范式

数据库三范式 &#xff1a;数据库三范式是指关系型数据库设计中的三种规范化设计原则&#xff0c;旨在减少数据冗余、提高数据一致性和可维护性。 第一范式&#xff1a;规定表中的每一列都应该是不可分割的最小单元。 为什么要这样实现呢&#xff1f; &#xff1a;举个栗子…

Kotlin(八) 数据类、单例

目录 一&#xff1a;创建数据类 二&#xff1a;单例类 一&#xff1a;创建数据类 和Java的不同&#xff0c;kotlin的数据类比较简单&#xff0c;New→Kotlin File/Class&#xff0c;在弹出的对话框中输入“Book”&#xff0c;创建类型选择“Data”。如图&#xff1a; 然后编…

VMware Horizon 8 2309 Enterprise虚拟桌面

VMware Horizon 8 2309 Enterprise虚拟桌面 一、虚拟桌面二、产品发布三、VMware Horizon 8 2309 Enterprise1.VMware Horizon 8 2309 Enterprise产品清单2.安装部署3. 优化工具总结 一、虚拟桌面 利用虚拟桌面和应用随时随地进行访问。 从云端进行管理 使用云端控制台和 Saa…

Docker swarm集群之compose启动多服务

Docker swarm集群之compose启动多服务 本篇文章是在搭建过Swarm集群基础上进行的&#xff0c;如未搭建过请移步 &#xff1a; [Docker swarm 集群搭建 - Wanwan’s Blog (wanwancloud.cn)] 环境信息 主机名IP主机配置master10.10.10.32c2gnode0110.10.10.42c2gnode0210.10.…

所有电商API接口,淘宝API接口分类,1688API、拼多多API、京东API

前往接入API 淘宝API item_get 获取商品详情 根据商品ID查询商品标题价格描述等详情数据 淘宝API item_search 按关键字搜索商品 搜索关键字&#xff0c;显示商品总数&#xff0c;标题&#xff0c;图片&#xff0c;优惠价等数据 淘宝API item_fee 获取商品快递费用 输入商品…

Java JVM垃圾回收确定垃圾的两种方式,GC Root

文章目录 前言一、如何确定是垃圾&#xff1f;引用计数法根可达路径法 二、GC Root1、以下可作为GC Root对象2、判断可回收&#xff1a;GC Root不可达3、真正宣告对象死亡需经过两次标记过程&#xff08;重要&#xff09; 前言 对于Java两种确定对象为可回收的两种方式&#x…

加解密原理(HCIA)

一、加密技术 1、加密的两个核心组件 2、加密技术作用&#xff1a; 二、加解密技术原理 1、对称加密 2、非对称加密 &#xff08;1&#xff09;思考问题&#xff1f; 1&#xff09;、有了非对称加密为什么还用对称加密&#xff1f; 2&#xff09;、如何传递秘钥呢&…

Megatron-LM GPT 源码分析(一) Tensor Parallel分析

引言 本文基于开源代码 GitHub - NVIDIA/Megatron-LM: Ongoing research training transformer models at scale &#xff0c;通过GPT的模型运行示例&#xff0c;从三个维度 - 模型结构、代码运行、代码逻辑说明 对其源码做深入的分析。 Tensor Parallel源码分析

基于RK3568高性价比全国产EMS储能解决方案(二)设计方案

目录 版 本 修 订 记 录 1. 产品介绍 1.1. 什么是XM3568-EP 1.2. 产品特点 1.3. 外壳尺寸 1.4. 外壳外观 1.5. 规格参数 2. 设备使用介绍 2.1. 下载需要使用到的驱动和调试工具 2.2. 启动网关 2.3. DEBUG串口的使用方法 2.4. LED指示灯说明 3. Linux系…

计算机网络(谢希仁)第八版课后题答案(第二章)

1.物理层要解决哪些问题&#xff1f;物理层的主要特点是什么&#xff1f; (1)物理层要尽可能地屏蔽掉物理设备和传输媒体&#xff0c;通信手段的不同&#xff0c;使数据链路层感觉不到这些差异&#xff0c;只考虑完成本层的协议和服务。 (2)给其服务用户&#xff08;数据链路…

MySQL(1):开始

概述 DB&#xff1a;数据库&#xff08;Database&#xff09; 即存储数据的“仓库”&#xff0c;其本质是一个文件系统。它保存了一系列有组织的数据。 DBMS&#xff1a;数据库管理系统&#xff08;Database Management System&#xff09; 是一种操纵和管理数据库的大型软件…

win10虚拟机安装教程

目录 1、安装VMware 10、12、16都可以&#xff0c;看个人选择 2、开始安装系统&#xff08;以vm16为例&#xff09; 3、在虚拟机中安装win10 完成 1、安装VMware 10、12、16都可以&#xff0c;看个人选择 下面链是我虚拟机安装包&#xff0c;需要可以下载。 YR云盘 软件安…

css:button实现el-radio效果

先看最终效果&#xff1a; ​​​ 思路&#xff1a; 一、 首先准备好按钮内容&#xff1a;const a [one,two,three] 将按钮循环展示出来&#xff0c;并设置一些样式&#xff0c;将按钮背景透明&#xff1a; <button v-for"(item,index) in a" :key"in…

【网络安全 --- 文件上传靶场练习】文件上传靶场安装以及1-5关闯关思路及技巧,源码分析

一&#xff0c;前期准备环境和工具 1&#xff0c;vmware 16.0安装 若已安装&#xff0c;请忽略 【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;提供资源&#xff09;-CSDN博客文章浏览阅读186次&#xff0c;点赞9次&#xff0c;收藏2次。【网络安全 --- 工…

如何配置微信小程序id

使用uni-app开发微信小程序项目&#xff0c;配置好微信小程序id是必不可少的。 一、如何找微信小程序id 二、如何配置微信小程序id