List类详解【c++】

news2024/11/25 4:59:53

在这里插入图片描述
🐔博主码云
🐔博主主页

目录

  • 🐓list简介
  • 🐓list使用
    • 🐤list构造函数
    • 🐤list迭代器
    • 🐤list capacity
    • 🐤list element access
    • 🐤list modifiers
    • 🐤list的迭代器失效
  • 🐓总结


🐓list简介

list是C++ STL中的一个双向链表容器,可以存储任何类型的元素。它提供了一组成员函数,可以在链表的任何位置插入和删除元素,也可以在链表的任何位置访问元素。与数组不同,list不需要连续的内存空间,因此可以动态地分配和释放内存。在插入和删除元素时,不会影响其他元素的位置,因此可以保持链表中元素的相对顺序。list支持双向迭代器,可以在正向和反向方向遍历链表。list是STL中的一个标准容器,可以在头文件中找到。它的常用操作包括创建list、插入元素、删除元素、访问元素、遍历std::list和其他常用函数等。

总的来说,list具有如下几个特性:

  • 元素按照它们在链表中的顺序存储,因此可以高效地在任何位置插入和删除元素。
  • 不支持随机访问,只能通过遍历链表来访问元素。
  • 支持双向迭代器,可以在正向和反向方向遍历链表。
  • 与数组不同,list不需要连续的内存空间,因此可以动态地分配和释放内存。
  • 在插入和删除元素时,不会影响其他元素的位置,因此可以保持链表中元素的相对顺序。

🐓list使用

🐤list构造函数

函数名特性
默认构造函数:list()该构造函数创建一个空的list对象。
拷贝构造函数:list(const list& l)该构造函数创建一个与l相同的list对象。
带有元素数量和元素值的构造函数:list(size_type n, const value_type& val = value_type())该构造函数创建一个包含n个元素,每个元素的值都为val的list对象。
带有迭代器范围的构造函数:list(InputIterator first, InputIterator last)该构造函数创建一个包含[first, last)范围内的元素的list对象。其中,first和last是迭代器,用于指定要复制到新list中的元素范围。

示例代码:

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

void print(list<int> ls)
{
	for (auto e : ls)
	{
		cout << e << ' ';
	}
	cout << endl;
}

int main()
{
	list<int> ls;
	print(ls);
	
	list<int> ls2(10, 6);
	print(ls2);
	
	list<int> ls3(ls2);
	print(ls3);
	
	list<int> ls4(ls2.begin(), ls2.end());
	print(ls4);	
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

注意:

  1. 在使用带有元素数量和元素值的构造函数时,如果元素类型是自定义类型,则必须提供接受一个值的构造函数,否则会导致编译错误。
  2. 在使用带有迭代器范围的构造函数时,迭代器的类型必须与list的元素类型相同,否则会导致编译错误。

🐤list迭代器

list提供了双向迭代器(bidirectional iterator),可以用于遍历list中的元素。list的迭代器定义在头文件中,可以使用list::iterator和list::const_iterator来表示可变和不可变的迭代器。

list的迭代器支持以下操作:

++it:将迭代器it移动到下一个元素。
–it:将迭代器it移动到上一个元素。
*it:返回迭代器it所指向的元素。
it->member:返回迭代器it所指向元素的成员member。
it == it2:比较两个迭代器是否相等。
it != it2:比较两个迭代器是否不相等。

函数声明特性
begin()和end()分别返回指向list首元素和尾元素下一个位置的迭代器。
rbegin()和rend()分别返回指向list尾元素和首元素前一个位置的逆向迭代器。

示例代码:

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

int main()
{
	string arr = "abcdefg";
	list<char> ls(arr.begin(), arr.end());
	list<char>::iterator it = ls.begin();
	list<char>::reverse_iterator rit = ls.rbegin();
	while (it != ls.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;
	while (rit != ls.rend())
	{
		cout << *rit << ' ';
		rit++;
	}
	cout << endl;
	return 0;
}

运行结果:
在这里插入图片描述

注意:

  1. list的迭代器不支持随机访问,因此不能使用it[n]来访问迭代器中的元素,也不能使用+和-运算符来移动迭代器。
  2. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
  3. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

🐤list capacity

list的容量是动态变化的,因此并没有capacity()函数来返回list的容量。以下是list的容量相关函数:

函数说明
size()返回list中元素的数量。
max_size()返回list最多可以容纳的元素数量,这个数量取决于系统的限制。
empty()判断list是否为空,如果list为空,则返回true,否则返回false。

示例代码:

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

int main()
{
	string arr = "abcdefg";
	list<char> ls(arr.begin(), arr.end());
	cout << "是否为空:" << ls.empty() << endl;
	cout << "最大存储数量:" << ls.max_size() << endl;
	cout << "当前存储数量:" << ls.size() << endl;
	return 0;
}

运行结果:
在这里插入图片描述

注意

  1. list的容量是动态变化的,因此在插入或删除元素时,list的容量可能会发生变化。

🐤list element access

list提供了一些用于访问元素的函数,如下

函数名说明
front()返回list中第一个元素的引用。
back()返回list中最后一个元素的引用。

示例代码:

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

int main()
{
	string arr = "abcdefg";
	list<char> ls(arr.begin(), arr.end());
	char front = ls.front();
	char back = ls.back();
	cout << front << "  " << back << endl;
	return 0;
}

运行结果:
在这里插入图片描述

注意

  1. 当容器为空时,调用front()和back()可能导致未定义行为,因此在使用这些方法之前最好检查容器是否为空。

🐤list modifiers

在C++中,list提供了多种操作函数来方便地对链表进行操作。其中,list中的modifiers函数主要用于修改链表中的元素,包括插入、删除和替换等操作。

以下是常用的list modifiers函数:

函数说明
push_back在链表的末尾插入一个元素。
push_front在链表的头部插入一个元素。
insert在指定位置插入一个元素。
erase删除指定位置的元素。
clear清空链表中的所有元素。
pop_back删除链表末尾的元素。
pop_front删除链表头部的元素。
swap用于交换两个链表的内容

示例代码:

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

template<typename T>
void Print(list<T> ls)
{
	for (const auto& e : ls)
	{
		cout << e << ' ';
	}
	cout << endl;
}

int main()
{
	list<char> ls;
	ls.push_back('A');
	ls.push_back('B');
	ls.push_back('C');
	Print(ls);

	ls.push_front('1');
	ls.push_front('2');
	ls.push_front('3');
	Print(ls);

	ls.pop_back();
	ls.pop_front();
	Print(ls);

	string arr = "abcd";
	ls.insert(ls.begin(), 'M');
	ls.insert(ls.end(), arr.begin(), arr.end());
	ls.insert(ls.begin(), 3, 'O');
	Print(ls);

	list<char> ls2(ls);
	ls.erase(ls.begin());
	Print(ls);

	ls.swap(ls2);
	Print(ls);
	Print(ls2);

	ls2.clear();
	ls.erase(ls.begin(), ls.end());
	Print(ls);
	Print(ls2);
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

注意:

  1. 在插入或删除元素时,要确保链表中已有足够的元素或者已经分配了足够的内存空间,否则可能会导致程序崩溃。
  2. 在使用insert函数时,需要注意插入位置的有效性,如果插入到了一个无效的位置,可能会导致程序出错。
  3. 在使用erase函数时,需要注意被删除元素的有效性,如果删除了一个无效的元素,可能会导致程序出错。
  4. 在使用clear函数时,需要注意清空链表后,链表中的所有元素都会被删除,因此需要确保不再需要这些元素的情况下才能使用该函数。
  5. swap函数只是交换了两个链表中的元素,而不是交换了它们的内存空间,因此不会对链表的容量和内存使用产生影响。

🐤list的迭代器失效

在使用list容器时,需要注意到删除节点会导致迭代器失效的问题。因为list容器的底层实现是双向链表,当我们删除某个节点时,该节点的前后节点会重新建立连接,而被删除节点的迭代器就会失效,指向该节点的迭代器将无法访问该节点,也无法访问其后继节点。

示例代码

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

int main()
{
	list<char> ls = {'a', 'b', 'c', 'd'};
	list<char>::iterator it = ls.begin();
	while (it != ls.end())
	{
		if (*it == 'b')
		{
			ls.erase(it);
		}
		cout << *it << ' ';
		it++;
	}
	return 0;
}

运行结果:
在这里插入图片描述
我们可以先保存指向要删除的节点的迭代器,然后将迭代器指向下一个节点,在进行删除操作。

int main()
{
	list<char> ls = {'a', 'b', 'c', 'd'};
	list<char>::iterator it = ls.begin();
	while (it != ls.end())
	{
		if (*it == 'b')
		{
			auto tmp = it++;
			ls.erase(tmp);
		}
		else
		{
			cout << *it << ' ';
			it++;
		}
	}
	return 0;
}

另外,当我们将迭代器保存到外部使用时也会导致迭代器失效。

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

int main() {
    std::list<int> mylist = { 1, 2, 3, 4, 5 };
    auto it = mylist.begin();

    // 将迭代器保存到外部使用
    auto outside_it = it;

    // 对list容器进行删除操作
    mylist.erase(mylist.begin());

    // 使用保存在外部的迭代器访问list容器
    std::cout << *outside_it << std::endl;

    return 0;
}

注意:

  1. 在使用迭代器遍历list容器时,不要在遍历过程中删除节点,因为删除节点会导致迭代器失效。如果需要在遍历过程中删除节点,可以先将迭代器指向下一个节点,再删除当前节点。
  2. 在使用迭代器遍历list容器时,不要将迭代器保存到容器外部使用,因为当我们对list容器进行插入或删除操作时,迭代器会失效,可能会导致程序崩溃或出现未定义行为。

🐓总结

list是C++ STL中的一个双向链表容器,可以在任意位置高效地插入和删除元素,不需要像vector那样移动其他元素。总之,list容器是一个高效的双向链表容器,可以在任意位置高效地插入和删除元素,是一个非常实用的容器。
在这里插入图片描述

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

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

相关文章

ETH-S7200-JM01以太网模块在纺机设备网络中应用成功案例分析

内容摘要 大家好&#xff0c;今天我们要为大家介绍一款神奇的设备——捷米特ETH-S7200-JM01以太网模块&#xff01;它可以让西门子PLC200 CPU226拥有以太网通讯接口&#xff0c;实现数据采集和生产管理系统构建。你以为这就是它的全部功能&#xff1f;那你就大错特错了&#x…

【STM32MP135】修改10.1寸屏1280x800分辨率配置,解决fb_size过小导致运行崩溃

文件路径&#xff1a;u-boot-stm32mp-v2021.10-stm32mp1-r1/configs/stm32mp13_defconfig

官网下载idea历史版本

1.进入官网 官网下载地址&#xff1a;https://www.jetbrains.com.cn/idea/ 进入后是这样的&#xff0c;如下图&#xff1a; 2.点击【下载】按钮&#xff0c;进入下载页面 &#xff08;上图中的两个地方的【下载】按钮是一样的&#xff09;。 3.选择右下角的【其他版本】就可…

LayUI入门,以及介绍

一.LayUI基本情况 1.LayUI介绍 Layui&#xff08;流行于 layui.com&#xff09;是一款轻量级的前端UI框架&#xff0c;专注于提供简洁、易用、灵活的界面组件和交互体验。它基于HTML5和CSS3技术&#xff0c;采用模块化开发的思想&#xff0c;提供了丰富的UI组件、常用的工具函数…

FTP服务器使用及配置

vsftp安装配置 环境配置 服务端:CentOS 7.6 vsftpd 客户端:Windows 10 xftp 服务端 yum -y install epel-release.noarchyum -y install vsftpd* pam* db4*systemctl restart vsftpd#修改配置前备份文件 [rootnode1 ~]# cd /etc/vsftpd/ [rootnode1 vsftpd]# ls ftpusers …

Eclipse调整系统字体(亲测)

1. 打开eclipse的菜单栏windows->preferences 2. 选择General->Appearance->colors and fonts 3. 选择字号&#xff0c;Apply&#xff0c;ok 建议选择常规18号&#xff0c;这样对眼睛友好一些&#xff0c;不易太大太小 为了大家更好的学习交流&#xff0c;博主新建了v…

算法训练营第三十五天||860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球

860.柠檬水找零 这道题自己不看答案能自己做出来 class Solution { public:bool lemonadeChange(vector<int>& bills) {if(bills[0]10 || bills[0]20) return false;int fivenum 0;int tennum 0;int tewentynum 0;for(int i 0;i<bills.size();i){if(bills[…

Hyper-V 虚拟机安装Ubuntu

Hyper-V 是win自带的虚拟机软件&#xff0c; 免费 进入控制面板&#xff0c;启用功能 勾选Hyper-V 然后重启电脑 打开 Hyper-v快速创建 此处可能需要 science surf network&#xff0c;否则创建虚拟机按钮为灰色 选择合适的版本&#xff0c;点击右下角的创建虚拟机进行安装&a…

【云时代数据利器】奥威BI SaaS版:一键链接云星空,套用百张报表

SaaS模式可以有效加快部署、提高效率、降低成本、提高灵活性&#xff0c;因此广受欢迎。随着市场的需求以及SaaS模式的广为人知&#xff0c;SaaS BI正逐渐成为BI的未来趋势之一&#xff0c;正逐渐成为云时代数据分析利器。奥威BI SaaS版和金蝶云星空标准方案强强联合&#xff0…

C++学习 结构体

目录 结构体 结构体定义和使用 结构体数组 结构体指针 结构体嵌套结构体 结构体做函数的参数 结构体中const使用场景 结构体 结构体定义和使用 定义&#xff1a; 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。 语法&#xff1a; struct 结构体…

day4 qtqtqtc++

cppcpp ui代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Widget</class><widget class"QWidget" name"Widget"><property name"geometry"><rec…

Linux--获取与杀死当前进程PID

获取当前进程的代码&#xff1a; #include <sys/types.h>pid_t idgetpid();//获取的是自己的进程PID 杀死当前进程的指令&#xff1a; kill -9 进程的PID 我要是kill -9 16865(-bash进程)&#xff0c;你会发现无论你输入clear、ls、还是vim...指令&#xff0c;都无…

云深处绝影四足机器人协议学习解析

绝影四足机器人通信协议学习解析 本学习文档介绍了云深处 绝影X20 四足机器人的通信协议&#xff0c;并对相关的通信机制和命令格式进行了简单的解析。该协议在机器人系统和上位机&#xff08;例如外部板卡或系统&#xff09;之间进行TCP通信时使用。 1. 协议端口号 在此协议…

定义一个派生自D1的D2类,并且在D2中覆盖pvf();建立一个D2类的对象并且调用f()、vf()、pvf()

运行代码&#xff1a; //定义一个派生自D1的D2类&#xff0c;并且在D2中覆盖pvf() //建立一个D2类的对象并且调用f()、vf()、pvf() #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class …

配置通过域名访问网站(NETBASE第七课)

1 DNS服务器 域名系统_百度百科 域名和与之相对应的IP地址转换的服务器 DNS&#xff08;Domain Name Server&#xff0c;域名服务器&#xff09;是进行域名(domain name)和与之相对应的IP地址 (IP address)转换的服务器。DNS中保存了一张域名(domain name)和与之相对应的IP地…

通过GitHub Desktop,将本地项目上传到gitee上

介绍 这里主要介绍&#xff0c;通过 gitHub Desktop 软件&#xff0c;将本地的项目&#xff0c;上传到 gitee的仓库里&#xff08;这里仓库为新建的仓库&#xff0c;什么东西都没有&#xff09;。 这里主要介绍&#xff0c;仓库的新建方式&#xff0c;及本地代码上传到远端的操…

Unity 实现一个揭面膜效果

源码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;

【Django】列表页面的搜索功能

目的 页面列表增加多字段搜索显示查询结果 方案 分页显示搜索结果 效果 实现 列表页面 # list.html <div class"pull-left" style"margin-bottom: 10px"><form action"{% url api-search %}" method"get"><div …

ModaHub魔搭社区:开源向量数据库的Milvus怎么读?

Milvus是一个中文词语,意为“Milvus navigate,为智慧找方向,为价值做链接,为创作者做伙伴”。在读这个词语时,可以按照以下方式发音: 首先,我们需要将Milvus这个词语分解成多个音节。根据汉语拼音的规则,可以将其分解为“mi”、“lu”、“su”。 接下来,我们需要根…

Java阶段五Day03

Java阶段五Day03 文章目录 Java阶段五Day03回顾git命令Git远程仓库远程仓库概念远程仓库分支操作分支管理策略 回顾git命令 本地版本控制 git initgit addgit commitgit loggit statusgit taggit refloggit reset 分支管理 git branchgit branch b1git checkout b1git merg…