当前位置: 首页 > article >正文

【C++】STL中的list容器详解及常用函数用法

个人主页: 起名字真南的CSDN博客

个人专栏:

  • 【数据结构初阶】 📘 基础数据结构
  • 【C语言】 💻 C语言编程技巧
  • 【C++】 🚀 进阶C++
  • 【OJ题解】 📝 题解精讲

目录

  • 📌 1 引言
  • 📌2 list容器
    • ✨2.1 list容器简介
    • ✨2.2 list容器结构
  • 📌3 list中主要成员函数
    • ✨ 3.1 构造函数初始化list
    • ✨ 3.2 迭代器遍历list容器
    • ✨ 3.3 对list的空间进行操作
    • ✨ 3.4 对list的元素进行访问
    • ✨ 3.5 对list的元素进行修改
      • 🚀3.5.1 push and pop
      • 🚀3.5.2 insert and erase
      • 🚀 3.5.3 swap and clear
  • 4 📌 参考文件

📌 1 引言

在C++的表中模板库(STL)中,list容器提供了一个双向链表的实现,他能高效的在任意位置进行插入和删除元素,非常适合需要频繁修改数据的场景。与vector不同,list是一个双向链表结构,并不支持快速随机访问。本文将详细介绍list容器的特点,使用场景,以及其主要成员函数的用法。

📌2 list容器

✨2.1 list容器简介

在这里插入图片描述

list 容器简介list 是一个双向链表数据结构,具有以下特点:

  • 高效插入和删除:在已知位置插入或删除元素的时间复杂度为 O(1),远高于 vector 的 O(n)。
  • 不支持随机访问:与数组不同,list 不支持通过下标访问,因此需要通过迭代器进行遍历。
  • 双向链表:支持从头部和尾部同时遍历,方便实现一些特定算法。

✨2.2 list容器结构

std::list 使用双向链表实现,每一个节点都包含了两个指针和一个数据字段

  • 数据字段 :用于储存数据
  • 前驱指针 :指向当前节点的前一个节点
  • 后继指针:指向当前接的后一个指针

在这种结构下,list容器还有一个头节点,它的前一个指针对应着尾节点,后一个指针对应着头节点。

  • 头指针 :指向链表中的第一个节点
  • 尾指针 :指向链表的最后一个节点

在这里插入图片描述

📌3 list中主要成员函数

✨ 3.1 构造函数初始化list

构造函数接口说明
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)用[first, last)区间中的元素构造list
#include<iostream>
#include<list>

using namespace std;

int main()
{
	list<int> l1;
	list<int> l2(6, 6);
	list<int> l3(l2);
	int arr[] = { 1,2,3,4,5, };
	list<int> l4(arr, arr + sizeof(arr) / sizeof(arr[0]));

	return 0;
}

调试结果:
在这里插入图片描述

✨ 3.2 迭代器遍历list容器

函数声明接口说明
begin + end返回第一个元素的迭代器 + 返回最后一个元素下一个位置的迭代器
rbegin + rend返回第一个元素的 reverse_iterator,即 end 位置,返回最后一个元素下一个位置的 reverse_iterator,即 begin 位置
list<int>l1(8, 8);
//使用l1的迭代器构造l2
list<int>l2(l1.begin(), l1.end());
//列表格式初始化C++11
list<int>l3{ 1,2,3,4,5,6,7,8,9 };

//使用迭代器的方式来遍历打印数组
int main()
{
	list<int>::iterator it = l1.begin();
	while (it != l1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	
	for (auto au : l3)
	{
		cout << au << " ";
	}
	cout << endl;
	
	auto l = l3.rbegin();
	while (l != l3.rend())
	{
		cout << *l << " ";
		l++;
	}
	cout << endl;
	return 0;
}

输出结果:
在这里插入图片描述
在这里插入图片描述
注意 :

  • 不管是使用正向迭代器还是反向迭代器,我们遍历的方法一直都是++控制。

✨ 3.3 对list的空间进行操作

在这里插入图片描述
在这里插入图片描述

函数声明接口说明
empty检测 list 是否为空,是返回 true,否则返回 false
size返回 list 中有效节点的个数
void test3()
{
	list<int> l1;
	list<int> l2(8,8);

	if (l1.empty())
	{
		cout << "l1 为空" << endl;
	}
	else
	{
		cout << "l1 不为空" << endl;
	}
	if (!(l2.empty()))
	{
		cout << "l2 不为空" << endl;
		cout << "l2.size() : " << l2.size() << endl;
	}

}

输出结果:
在这里插入图片描述
注意 :

  • 在这串代码中empty()的函数返回值是bool,如果为空则返回true,不为空返回false

✨ 3.4 对list的元素进行访问

在这里插入图片描述
在这里插入图片描述

函数声明接口说明
front返回 list 的第一个节点中值的引用
back返回 list 的最后一个节点中值的引用
void test4()
{
	list<int> l1{ 1,2,3,4,5,6,7,8,9,10 };

	cout << "l1.front(): " << l1.front() << endl;
	cout << "l1.back(): " << l1.back() << endl;
}

输出结果:
在这里插入图片描述
注意 :

  • 在list中不能随机访问链表中的元素,只能通过front和back来获取头结点的数据和尾节点的数据

✨ 3.5 对list的元素进行修改

函数声明接口说明
push_frontlist 首元素前插入值为 val 的元素
pop_front删除 list 中第一个元素
push_backlist 尾部插入值为 val 的元素
pop_back删除 list 中最后一个元素
insertlistposition 位置中插入值为 val 的元素
erase删除 listposition 位置的元素
swap交换两个 list 中的元素
clear清空 list 中的有效元素

🚀3.5.1 push and pop

在这里插入图片描述
在这里插入图片描述

在容器的开始位置插入元素
来list容器的开始位置插入一个新的元素,在它当前的第一个元素之前将val的值移到第一个元素中。
增加一个容量。
在容器的末尾位置插入元素
来list容器的开始位置插入一个新的元素,在它当前的第一个元素之前将val的值移到第一个元素中。
增加一个容量。

void test5()
{
	list<int> l1{ 1,2,3,4,5,6,7,8,9 };
	l1.push_front(0);
	l1.push_back(10);
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;
}

输出结果:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

将list中第一个元素删除,减少一个容量。
将list中末尾元素删除,减少一个容量。

void test5()
{
	list<int> l1{ 1,2,3,4,5,6,7,8,9 };
	l1.push_front(0);
	l1.push_back(10);
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

	l1.pop_back();
	l1.pop_front();

	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;
}

输出结果:
在这里插入图片描述

🚀3.5.2 insert and erase

在这里插入图片描述

insert 在pos位置的数据前面插入一个数据
从图中我们可以看到传的参数可以是迭代器位置,也可以是一个迭代器区间

void test6()
{
	
	list<int> l1{0,1,2,3,5,6,7,8,9 };
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

	l1.insert(l1.begin(), 18);
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

}

输出结果:
在这里插入图片描述

在这里插入图片描述

erase 将pos位置的数据删除
从图中可以看到参数可以是一个迭代器区间也可以是一个位置

void test6()
{
	
	list<int> l1{0,1,2,3,5,6,7,8,9 };
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

	l1.erase(--l1.end());
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

}

输出结果:
在这里插入图片描述
注意 :

  • 在我们erase的时候需要注意关于迭代器失效的问题,在我们调用erase是必须保证他指向了一个有效的位置,如果代码中使用l1.erase(l1.end())在我们删除最后一个元素的时候他指向了最后一个数据的尾巴所以会造成迭代器失效

🚀 3.5.3 swap and clear

在这里插入图片描述

交换两个相同类型容器的元素

	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

	list<int> l2(6, 6);
	for (auto it : l2)
	{
		cout << it << " ";
	}
	cout << endl;
	swap(l1, l2);
	for (auto it : l1)
	{
		cout << it << " ";
	}
	cout << endl;

	for (auto it : l2)
	{
		cout << it << " ";
	}

输出结果:
在这里插入图片描述

在这里插入图片描述

清空list中所有有效元素

	l1.clear();
	l2.clear();

调试结果:
在这里插入图片描述

4 📌 参考文件

传送门: C++Reference



http://www.kler.cn/a/388351.html

相关文章:

  • kettle开发-Day43-数据对比
  • Unity资源打包Addressable资源保存在项目中
  • [ComfyUI]Flux:繁荣生态魔盒已开启,6款LORA已来,更有MJ6写实动漫风景艺术迪士尼全套
  • 【韩老师零基础30天学会Java 】07章 面向对象编程(基础)
  • 运行springBlade项目历程
  • 使用Matlab神经网络工具箱
  • UOS启动器
  • CI/CD 实践总结
  • HTB:Explore[WriteUP]
  • [Android]查找java类中声明为native方法的具体实现方法
  • 「QT」几何数据类 之 QPolygon 多边形类
  • 增删改查基础项目总结
  • 智能机器人技术:AI 如何赋予机器智能行动
  • 如何使用 Puppeteer 和 Browserless 抓取亚马逊产品数据?
  • 【SQL实验】更新操作
  • 量子计算及其在密码学中的应用
  • Element UI组件Dialog显示闪动问题【解决方案】
  • The First项目报告:MANTRA如何实现世界金融区块链化?
  • 统信UOS开发环境支持Perl
  • 力扣第46题“全排列”
  • 计算机视觉系列----深入浅出了解计算机视觉
  • Leetcode:540. 有序数组中的单一元素
  • Kafka面试题 part-1
  • Unet++改进16:添加DoubleAttention||减少冗余计算和同时存储访问
  • 算法求解 -- (炼码 3853 题)检查是否有路径经过相同数量的0和1
  • 自动化测试工具Ranorex Studio(二十三)-等待UI元素-库超时