C++STL序列式容器——list容器及其常用操作(详解)

news2024/10/7 0:42:38

在这里插入图片描述
纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。

💬文章目录

    • 一.list容器基本概念
    • 二.list容器的常用操作
      • list构造函数
      • list迭代器获取
      • list特性操作
      • list元素操作
      • list赋值操作
      • list的交换、反转、排序、归并操作
      • list比较操作
      • list插入和删除操作

一.list容器基本概念

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:

  • 一个是存储数据元素的数据域。
  • 另一个是存储下一个结点地址的指针域。
    在这里插入图片描述

list容器的数据结构是一个有头双向循环链表。链表其优缺点为:

  • 采用动态存储分配,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
  • 链表灵活,但是空间和时间额外耗费较大

list容器的迭代器:
list容器不能像vector一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。list迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取操作。所谓”list正确的递增,递减、取值、成员取用”是指,递增时指向下一个节点,递减时指向上一个节点,取值时取的是节点的数据值,成员取用时取的是节点的成员。由于list还是一个双向链表,迭代器必须能够具备前移、后移的能力,所以list容器提供的是双向迭代器(Bidirectional Iterators).
在这里插入图片描述

二.list容器的常用操作

list构造函数

注:使用list容器时,需包含头文件#include <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>& mylist)//形参使用const,避免被修改
{//const_iterator只读迭代器
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test()
{
	list<char> mylist1;//list采用模板实现类实现(显示实例化),对象的默认构造形式。
	list<int> mylist2(10, 6); //构造函数将n个elem拷贝给本身。
	list<int> mylist3(++mylist2.begin(), --mylist2.end());//构造函数将[beg, end)区间中的元素拷贝给本身。
	list<int> mylist4(mylist2);//拷贝构造函数

	printList(mylist2);
	printList(mylist3);
	printList(mylist4);
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

list迭代器获取

函数原型解释
iterator begin();返回指向开始位置的迭代器,iterator是正向迭代器。只能使用++运算符从左向右遍历容器,每次沿容器向右移动一个元素
const_iterator begin();返回指向开始位置并且为常量的迭代器
const_iterator cbegin();返回指向开始并且为常量的迭代器,const_iterator 常正向迭代器。函数作用:配合auto使用
iterator end();返回指向末尾元素的下一个位置的迭代器
const_iterator end();返回指向末尾元素的下一个位置并且为常量的迭代器
const_iterator cend();返回指向末尾元素的下一个位置的并且为常量的迭代器,函数作用:配合auto使用
reverse_iterator rbegin();返回反向迭代器,指向末尾元素下一个位置,操作都是往相反反向,reverse_iterator 为反向迭代器
const_reverse_iterator crbegin();返回反向迭代器,指向末尾元素下一个位置,操作都是往相反反向,并且为常量属性,const_reverse_iterator 常反向迭代器。
reverse_iterator rend();返回反向迭代器,指向开头元素的位置,操作都是往相反反向
const_reverse_iterator cre nd();返回反向迭代器,指向开头元素的位置,操作都是往相反反向,并且为常量属性

注意:begin函数和cbegin函数都可以返回const_iterator,那么为什么要两个函数呢?
因为begin函数有重载,无法配合auto(自动推导数据类型)使用,所以才多出一个cbegin函数。

list特性操作

函数原型解释
size_t size() const;返回容器的实际大小(已使用的空间)。
bool empty() const;判断容器是否为空。
void clear();清空容器。
void resize(size_t size);把容器的实际大小置为size,如果size<实际大小,会截断多出的部分;如果size>实际大小,则以默认值0填充新位置
void resize(size_t size,const T &value);把容器的实际大小置为size,如果size<实际大小,会截断多出的部分;如果size>实际大小,就用value填充。

实例:特性函数演示

#include <iostream>
using namespace std;
#include <list>//包含头文件
void printList(const list<int>& mylist)//形参使用const,避免被修改
{//const_iterator只读迭代器
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test()
{
	list<int> mylist;
	for (int i = 0; i < 5; i++)
	{
		mylist.push_back(i + 1);
	}

	cout << "size:" << mylist.size() << endl;//5

	cout << mylist.empty() << endl;//0
	if (mylist.empty())
	{
		cout << "空" << endl;
	}
	else
	{
		cout << "不为空" << endl;
	}

	mylist.resize(3);
	printList(mylist);//1 2 3

	mylist.resize(5);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
	printList(mylist);//1 2 3 0 0

	mylist .resize(10, 6);//如果容器变长,也可以用value填充
	printList(mylist);//1 2 3 0 0 6 6 6 6 6 
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

list元素操作

函数原型解释
T& front();返回第一个元素。
T& back();返回最后一个元素。

list赋值操作

作用:通过重载赋值运算符operator=和成员函数assign(),给已存在的容器赋值,将覆盖容器中原有的内容。

函数原型解释
list assign(beg, end);将[beg, end)区间中的数据拷贝赋值给本身。
void assign(const size_t n, const T& value);将n个elem拷贝赋值给本身。
list& operator=(const list &lst);重载等号操作符,把容器l赋值给当前容器。

实例:赋值操作演示

#include <iostream>
using namespace std;
#include <list>//包含头文件
#include<algorithm>
void printList(const list<int>& mylist)//形参使用const,避免被修改
{//const_iterator只读迭代器
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void test()
{
	list<int> mylist;
	mylist.assign(10, 10);
	printList(mylist);

	list<int> mylist2;
	mylist2.assign(mylist.begin()++, mylist.end()--);
	printList(mylist2);

	cout << mylist.front() << endl;
	cout << mylist.back() << endl;
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

list的交换、反转、排序、归并操作

函数原型解释
void swap(list<T> &l);把当前容器与l交换,交换的是链表结点的地址。
void reverse();反转链表。
void sort();对容器中的元素进行升序排序。
void sort(_Pr2 _Pred);对容器中的元素进行排序,排序的方法由_Pred决定(二元函数)。
void merge(list< T> &l);采用归并法合并两个已排序的list容器,合并后的list容器仍是有序的。

实例:list的交换、反转、排序、归并操作演示

#include <iostream>
using namespace std;
#include <list>//包含头文件
#include<algorithm>
void printList(const list<int>& mylist)//形参使用const,避免被修改
{//const_iterator只读迭代器
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
bool myfunc2(int v1, int v2)
{
	return v1 > v2;
}
void test()
{
	list<int> mylist;
	for (int i = 0; i < 5; i++)
	{
		mylist.push_back(i + 10);//10 11 12 13 14
	}
	list<int> mylist2;
	for (int i = 0; i < 5; i++)
	{
		mylist2.push_back(i);//0 1 2 3 4
	}

	mylist2.swap(mylist); //把当前容器mylist2与mylist交换,交换的是链表结点的地址。
	printList(mylist2);//10 11 12 13 14

	mylist2.reverse();//反转链表

	printList(mylist2);//14 13 12 11 10

	//注意:list容器不能使用sort算法,list容器有自己专属的sort成员函数
	//sort(mylist.begin(), mylist.end());
	
	mylist2.sort(myfunc2);//借助myfunc2函数进行比较,然后sort降序排列
	printList(mylist2);//14 13 12 11 10

	mylist2.sort();//mylist2链表使用sort函数默认升序排列
	printList(mylist2);//10 11 12 13 14

	mylist.sort();//mylist链表使用sort函数默认升序排列
	printList(mylist);//0 1 2 3 4 

	mylist2.merge(mylist); //采用归并法合并两个已排序的list容器,合并后的list容器仍是有序的
	printList(mylist2); //0 1 2 3 4 10 11 12 13 14

}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

list比较操作

函数原型解释
bool operator == (const vector<T> & l) const;重载==运算符,判断当前链表与l是否相等
bool operator != (const vector<T> & l) const;重载!=运算符,判断当前链表与l是否不相等

list插入和删除操作

函数原型解释
void push_front(const T& ele);在容器头部插入一个数据
void push_back(const T& ele);尾部插入元素ele
void pop_front();删除容器第一个数据
void pop_back();删除最后一个元素
iterator insert(iterator pos, const T& value);在指定位置插入一个元素,返回指向插入元素的迭代器。
iterator insert(pos,n,elem);在pos位置插入n个elem数据,返回指向第一个插入元素的迭代器。
iterator insert(iterator pos, iterator first, iterator last);在指定位置插入一个区间的元素,返回指向第一个插入元素的迭代器。
iterator erase(iterator pos);删除指定位置的元素,返回下一个有效的迭代器。
iterator erase(iterator first, iterator last);删除指定区间的元素,返回下一个有效的迭代器。
splice(iterator pos, const vector< T> & l);把另一个链表连接到当前链表pos位置处。
splice(iterator pos, const vector< T> & l, iterator first, iterator last);把另一个链表指定的区间连接到当前链表pos位置处。
splice(iterator pos, const vector< T> & l, iterator first);把另一个链表从first开始的结点连接到当前链表pos位置处。
void remove(const T& value);删除链表中所有值等于value的元素。
void remove_if(_Pr1 _Pred);删除链表中满足条件的元素,参数_Pred是一元函数。
void unique();删除链表中相邻的重复元素,只保留一个。

list插入和删除操作演示:

#include <iostream>
using namespace std;
#include <vector>
#include <list>//包含头文件
void printList(const list<int>& mylist)//形参使用const,避免被修改
{//const_iterator只读迭代器
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
bool myfunc(int val)
{
	return val > 300;
}
void test()
{
	list<int> mylist;
	mylist.push_back(10);//在容器尾部插入一个数据
	mylist.push_back(20);
	mylist.push_back(30);
	mylist.push_back(40);
	mylist.push_back(50);
	
	mylist.push_front(100);//在容器头部插入一个数据
	mylist.push_front(200);
	mylist.push_front(300);
	mylist.push_front(400);

	printList(mylist);//400 300 200 100 10 20 30 40 50
	cout << "------------------" << endl;

	list<int>::const_iterator it = mylist.insert(mylist.begin(), 2, 0);//在pos位置插入n个elem数据
	cout << *it << endl;//返回指向第一个插入元素的迭代器。
	cout << "------------------" << endl;

	vector<int> v;
	v.push_back(1000);
	v.push_back(2000);
	v.push_back(3000);

	mylist.insert(mylist.begin(), v.begin(), v.end()); //在指定位置插入一个区间的元素,返回指向第一个插入元素的迭代器
	printList(mylist);//1000 2000 3000 400 300 200 100 10 20 30 40 50
	cout << "------------------" << endl;

	mylist.erase(mylist.begin());//删除第一个元素
	printList(mylist); //2000 3000 400 300 200 100 10 20 30 40 50
	cout << "------------------" << endl;

	list<int> mylist2(6,6);

	mylist.splice(mylist.end(),mylist2);//将mylist2链接到mylist后
	printList(mylist);//2000 3000 400 300 200 100 10 20 30 40 50 6 6 6 6 6 6
	cout << "------------------" << endl;

	mylist.remove(300); //删除链表中所有值等于300的元素
	printList(mylist);//2000 3000 400 200 100 10 20 30 40 50 6 6 6 6 6 6
	cout << "------------------" << endl;

	mylist.remove_if(myfunc);//删除链表中所有值大于300的元素
	printList(mylist);// 200 100 10 20 30 40 50 6 6 6 6 6 6
	cout << "------------------" << endl;
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

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

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

相关文章

NSToolbar 及自定义

文章目录 自定义 item添加系统自带 item自定义 item 需要显示图片时,item 不设置title- (void)showWindow1{NSWindowStyleMask windowStyles = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturiza

基于java的坦克大战游戏的设计与实现--答辨PPT--【毕业论文】

文章目录 本系列校训毕设的技术铺垫PPT主体层次封面页目录页&#xff1a;设计工具与相关技术&#xff1a;系统分析总体设计&#xff1a;详细设计测试结论&#xff1a; 小技巧 本系列校训 互相伤害互相卷&#xff0c;玩命学习要你管&#xff0c;天生我才必有用&#xff0c;我命…

MySQL绿色安装和配置

1、 从地址http://dev.mysql.com/downloads/mysql/中选择windows的版本下载。 2、 mysql各个版本的简介 &#xff08;1&#xff09; MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;但不提供官方技术支持。 &#xff08;2&#xff09; MySQL Enterprise Ed…

自定义view - 炫酷进度条

1. 思路分析 自定义View步骤&#xff1a; 1>&#xff1a;values__attrs.xml&#xff0c;自定义属性&#xff1b; 2>&#xff1a;在第三个构造方法中&#xff0c;获取自定义属性&#xff1b; 3>&#xff1a;onMeasure&#xff1a;不是非必须的&#xff0c;测量控件大小…

基于SSM的简易图书管理系统

基于SSM的简易图书管理系统说明书 目录 1.系统设计... 1 1.1背景意义... 1 1.2创新性... 1 1.3功能介绍... 1 1.4应用价值... 1 2.系统启动与使用... 2 2.1下载系统压缩包并解压... 2 2.2打开系统文件夹... 3 2.3 SSM必需maven依赖加载和tomcat配置... 4 2.4启动系统... 5 2.5进…

SSM游戏社交网站【纯干货分享,免费领源码05667】

目 录 摘要 1 绪论 1.1 研究意义 1.2研究方法 1.3ssm框架 1.4论文结构与章节安排 2 2 游戏社交网站系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1功能性分析 2.3.2非功能性分析 2…

采集设置为固定值或随机值

网站采集软件怎么采集设置为固定值或随机值&#xff1f; 1. 设置为固定值 例如在简数采集器&#xff0c;进入对应的详情提取器字段数据处理&#xff0c;xpath值为空&#xff0c;然后空内容缺省值设置为固定值&#xff0c;例如示例图的填写为最新资讯&#xff0c;保存完成。 2.…

关于使用easyExcel读取前端文件和MybatisPlus批量插入

关于使用easyExceld读取前端文件和MybatisPlus批量插入 文章目录 关于使用easyExceld读取前端文件和MybatisPlus批量插入实体类监听器开始调用可能出现的问题最后&#xff0c;关于MybatisPlus的批量插入写一个工具类写一个配置类到Mappe中添加这个方法 最近写项目&#xff0c;后…

SUSE 宣布开发与 RHEL 兼容的 Linux 发行版

导读近日消息&#xff0c;SUSE 在今天宣布&#xff0c;它将 fork 公开可用的 Red Hat Enterprise Linux (RHEL)&#xff0c;并将开发和维护与 RHEL 兼容的发行版&#xff0c;所有人都可以不受限制地使用该发行版本。未来几年&#xff0c;SUSE 计划向该项目投资超过 1000 万美元…

分布式训练数据并行极致优化:ZeRO

分布式训练数据并行极致优化&#xff1a;ZeRO 导言 随着 ChatGPT 的爆火&#xff0c;大模型成为了近些年人工智能的研究热点。大模型能力惊艳&#xff0c;但是训练起来成本也不小。大模型&#xff0c;顾名思义&#xff0c;最大的特点就是 “大”。这里的 “大” 通常指的就是…

本地部署 Stable Diffusion XL 1.0 Gradio Demo WebUI

StableDiffusion XL 1.0 Gradio Demo WebUI 0. 先展示几张 StableDiffusion XL 生成的图片1. 什么是 Stable Diffusion XL Gradio Demo WebUI2. Github 地址3. 安装 Miniconda34. 创建虚拟环境5. 安装 Stable Diffusion XL Gradio Demo WebUI6. 启动 Stable Diffusion XL Gradi…

c语言内存函数的深度解析

本章对 memcpy&#xff0c;memmove&#xff0c;memcmp 三个函数进行详解和模拟实现&#xff1b; 本章重点&#xff1a;3个常见内存函数的使用方法及注意事项并学会模拟实现&#xff1b; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力…

基于深度学习的裂纹图像分类研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2023最新ChatGPT商业运营版网站源码+支持ChatGPT4.0+GPT联网+支持ai绘画(Midjourney)+支持Mind思维导图生成

本系统使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到本系统&#xff01; 支持GPT3模型、GPT4模型Midjourney专业绘画&#xff08;全自定义调参&#xff09;、Midjourney以图生图、Dall-E2绘画Mind思维导图生成应用工作台&#xff08;Prompt&#xff09;AI绘画广场自定…

行业动态 - Zhaga 常见问题解答

本文采用chatGPT 3.5翻译润色&#xff0c;内容来自于Zhaga联盟官网Zhaga FAQ [1]&#xff0c;原文网页提供了更多的延伸阅读资料&#xff0c;可点击文末链接访问。另外不得不说&#xff0c;chatGPT对文字的优化调整功能太好用了。 ​ 1. "Zhaga"这个名字的由来和含义…

Nuxt 菜鸟入门学习笔记二:配置

文章目录 Nuxt 配置环境覆盖环境变量和私有令牌 应用配置runtimeConfig 与 app.config外部配置文件Vue 配置支持配置 Vite配置 webpack启用试验性 Vue 功能 Nuxt 官网地址&#xff1a; https://nuxt.com/ 默认情况下&#xff0c;Nuxt 的配置涵盖了大多数用例。nuxt.config.ts …

【雕爷学编程】Arduino动手做(172)---WeMos D1开发板模块4

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

为什么 Raft 原生系统是流数据的未来

虽然Apache Kafka正在逐步引入KRaft以简化其一致性方法&#xff0c;但基于Raft构建的系统对于未来的超大规模工作负载显示出更多的潜力。 ​共识是一致性分布式系统的基础。为了在不可避免的崩溃事件中保证系统的可用性&#xff0c;系统需要一种方式来确保集群中的每个节点保持…

快速跑 nerf instant-ngp 快速调试与配置,跑自己的数据

1.下载Anaconda3 2.打开Anaconda Prompt (Anaconda) 创建虚拟环境 conda create -n nerf-ngp python3.8切换到虚拟环境 conda activate nerf-ngp安装相关依赖包 pip install commentjson imageio numpy opencv-python-headless pybind11 pyquaternion scipy tqdm安装完毕后…

现在设计师都在用哪些工具做UI设计

随着国内企业在用户交互方面的竞争&#xff0c;UI设计的未来是无限的。 如果你仍然或只是在寻找一个合适的UI设计工具&#xff0c;那么这篇文章应该非常适合你。 1.即时设计 即时设计是一款免费的在线 UI 设计工具&#xff0c;无系统限制&#xff0c;浏览器打开即可使用&…