【C++】list的介绍及使用说明

目录

00.引言

01.list的介绍

模版类

独立节点存储

list的使用

1.构造函数

2.迭代器的使用

分类

运用

3.容量管理

empty():

size():

4.元素访问

5.增删查改


00.引言

我们学习数据结构时,学过两个基本的数据结构:顺序表链表顺序表中的数据是连续存储的,并且支持随机访问,但是增删数据的效率比较低,因为要挪动数据;链表中的数据是分散存储的,每个节点包含一个数据和指向令一个节点的指针,不支持随机访问,但插入和删除操作的效率较高。

vector容器内部数据存储原理可以认为是顺序表,而list可以认为是双向链表(每个节点都包含指向前一个和后一个节点的指针)。

01.list的介绍

模版类

和"std::vector"一样,“std::list”实现不同类型数据的管理也是通过模版类的机制实现的。当创建一个list对象时,可以通过模版参数来指定存储的元素类型。使用"<数据类型>"来显式实例化指定存储的元素类型,例如“std::list<int>”表示存储整数类型的链表,“std::list<double>”表示存储双精度浮点型的链表……

#include <iostream>template<typename T>
class list {……
};int main() {list<int> myList1;list<double> myList2;return 0;
}

独立节点存储

list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。因此list可以在任意位置进行插入和删除,且时间复杂度为O(1),并且该容器可以前后双向迭代。

list的使用

在cpluscplus网站上有具体的list的使用说文档:list使用文档,在实际运用中,需要熟悉一些常用的list接口,以下列出了一些常见接口:

1.构造函数

在使用list创建对象之前,需要包含头文件“<vector>”。

我们需要调用构造函数来创建对象,list的构造函数有以下几种:

1.list():无参构造

2.list(size_type n,const value_type& val = value_type()):初始化n个val的元素

3.list(const list& x):拷贝构造函数

4.list(inputiterator first, inputiterator last):用(first,last)区间中的元素构造

代码演示:


void text1()
{list<int> l1;list<int> l2(5, 10);list<int> l3(l2);list<int> l4(l3.begin(), l3.end());int arr[] = { 0,1,2,3,4 };list<int> l5(arr, arr + 5);
}

运行结果:

2.迭代器的使用

可以将 list 中的迭代器理解为一个指针,该指针指向list中的某一个节点

分类

    · begin + end:返回第一个数据位置的迭代器 + 返回最后一个数据的下一个位置的迭代器

    · rbegin + rend:返回第一个元素的reverse_iterator,即end位置 + 返回最后一个元素下一个位置的reverse_iterator,即begin位置

注意:

1.begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

2.rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

运用

遍历list只能用迭代器和范围for,而vector还可以用类似与数组的下标[]访问,那是因为vector中的数据是连续存储的,而list中是分散存储的,元素地址直接并无关联。

迭代器和范围for遍历:


void text2(const list<int>& l)
{for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it) {cout << *it << " ";//*it = 10; 编译不通过}cout << endl;
}
int main() {//text1();list<int> l{ 1,2,3,4,5,6,7,8,9 };text2(l);return 0;
}

运行结果: 

可以看到这里使用的是const迭代器,这表示迭代器指向的元素是不可被修改的,来看看const_iterator的底层是这样定义的:

class list {
public:// other members...// 内部定义 const_iteratortypedef const T* const_iterator;
};

所以const迭代器指向的元素是常量,不可进行修改操作,而迭代器本身是可以++或--的,如果是

typedef T* const const_iterator;

这种方式定义,则表示迭代器本身不可++或--操作,其指向的元素则可以被修改。

正向反向迭代器:


void text3()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin();   // C++98中语法auto it = l.begin();                     // C++11之后推荐写法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}int main() {text3();return 0;
}

运行结果: 

在C++11中引入了auto关键字,编译器会自动推导auto定义的变量的类型,具体内容可以参考我的这篇博客:auto关键字与基于范围的for循环(C++11)

3.容量管理

list虽然不需要动态开辟管理内存空间,但是还是要对节点的数量(数据的个数)进行跟踪管理

empty():

用于检查列表是否为空。如果列表为空,则返回 ‘true’,否则返回 ‘false’。

代码演示:


void text4()
{list<int> myList;if (myList.empty()) {std::cout << "List is empty!" << std::endl;}else {std::cout << "List is not empty. Size: " << myList.size() << std::endl;}}int main() {text4();return 0;
}

 运行结果:

size():

用于获取列表中的数量。

代码演示:


void text5()
{list<int> myList = { 1, 2, 3, 4, 5 };std::cout << "Size of list: " << myList.size() << std::endl;
}int main() {text5();return 0;
}

运行结果:

4.元素访问

有别与begin、end,list中可以通过front、back函数分别获取list的第一个节点的引用和最后一个节点的引用,是直接获取元素本身,而不是元素地址(指向元素的迭代器(指针))。

代码演示:

void text6()
{list<int> myList = { 1, 2, 3, 4, 5 };int firstElement = myList.front();cout << "First element: " << firstElement << endl;int lastElement = myList.back();cout << "Last element: " << lastElement << endl;}int main() {text6();return 0;
}

5.增删查改

下面是代码演示:


void PrintList(const list<int>& l)
{// 注意这里调用的是list的 begin() const,返回list的const_iterator对象for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it){cout << *it << " ";// *it = 10; 编译不通过}cout << endl;
}// list插入和删除
// push_back/pop_back/push_front/pop_front
void Test1()
{int array[] = { 1, 2, 3 };list<int> L(array, array + sizeof(array) / sizeof(array[0]));// 在list的尾部插入4,头部插入0L.push_back(4);L.push_front(0);PrintList(L);// 删除list尾部节点和头部节点L.pop_back();L.pop_front();PrintList(L);
}// insert /erase 
void Test2()
{int array1[] = { 1, 2, 3 };list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));// 获取链表中第二个节点auto pos = ++L.begin();cout << *pos << endl;// 在pos前插入值为4的元素L.insert(pos, 4);PrintList(L);// 在pos前插入5个值为5的元素L.insert(pos, 5, 5);PrintList(L);// 在pos前插入[v.begin(), v.end)区间中的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());PrintList(L);// 删除pos位置上的元素L.erase(pos);PrintList(L);// 删除list中[begin, end)区间中的元素,即删除list中的所有元素L.erase(L.begin(), L.end());PrintList(L);
}// resize/swap/clear
void Test3()
{// 用数组来构造listint array1[] = { 1, 2, 3 };list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));PrintList(l1);// 交换l1和l2中的元素list<int> l2;l1.swap(l2);PrintList(l1);PrintList(l2);// 将l2中的元素清空l2.clear();cout << l2.size() << endl;
}int main() {Test1();Test2();Test3();return 0;
}

运行结果: 

以上就是关于list的介绍和使用说明的有关知识了,欢迎在评论区留言~感觉这篇博客对您有帮助的可以点赞关注支持一波喔~😉 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++中程序内存区域划分

总结C/C中程序内存区域划分 C/C程序内存分配的几个区域&#xff1a; 1. 栈区&#xff08;stack&#xff09;&#xff1a;在执⾏函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的…

【观察】容器化部署“再简化”,云原生体验“再升级”

自2013年云原生概念被提出以来&#xff0c;云原生技术和架构在过去十多年得到了迅速的发展&#xff0c;并对数字基础设施、应用架构和应用构建模式带来了深刻的变革。根据IDC预测&#xff0c;到2024年&#xff0c;新增的生产级云原生应用在新应用的占比将从2020年的10%增加到60…

2021年全国大学生电子设计竞赛D题——基于互联网的摄像测量系统(二)

09 电路设计 前面介绍了系统的硬件框图如下&#xff1a; 硬件基本分为三块&#xff0c;两个摄像节点&#xff0c;一个终端节点。 1. 摄像节点硬件 摄像节点由一个DE10-Nano开发板和一个D8M摄像头实现&#xff0c;DE10-Nano开发板的HDMI接口外接HDMI显示器来显示拍摄到的视频。…

Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例

概述 Objective-C开发中&#xff0c;网络数据捕获是一项常见而关键的任务&#xff0c;特别是在处理像RSS源这样的实时网络数据流时。MWFeedParser库作为一个优秀的解析工具&#xff0c;提供了简洁而强大的解决方案。本文将深入介绍如何利用MWFeedParser库&#xff0c;以高效、…

时序预测 | Transformer时间序列预测 Matlab代码

文章目录 效果一览文章概述源码设计参考资料 效果一览 文章概述 1.时序预测 | Transformer时间序列预测 Matlab代码 2.单变量时间序列预测&#xff1b; 3.多指标评价&#xff0c;评价指标包括&#xff1a;R2、MAE、MBE等&#xff0c;代码质量极高&#xff1b; 4.excel数据&…

【Qt 学习笔记】Qt常用控件 | 显示类控件Progress Bar的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 显示类控件Progress Bar的使用及说明 文章编号&#xff…

ollama大语言模型

查看已经安装的大语言模型 ollama list运行大语言模型 ollama run llama2:latest

【计算机毕业设计】微信小程序:MHK自学平台的设计与实现——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

数据结构(顺序栈

目录 1. 讲解&#xff1a;2. C代码实现&#xff1a;小结&#xff1a; 1. 讲解&#xff1a; 用顺序的物理结构&#xff08;数组&#xff09;存储栈这个数据结构&#xff0c;实现栈的创建、销毁、增删查、判空。 top指针的指向位置有两种实现方法&#xff1a;一个是指向栈顶元素…

力扣(leetcode) 42. 接雨水 (带你逐步思考)

力扣(leetcode) 42. 接雨水 &#xff08;带你逐步思考&#xff09; 链接&#xff1a;https://leetcode.cn/problems/trapping-rain-water/ 难度&#xff1a;hard 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多…

二刷大数据(三)- Flink1.17

目录 Flink概念与SparkStreaming区别分层API 工作流程部署模式**Local Mode****Standalone Mode****YARN Mode****Kubernetes Mode****Application Mode** 运行架构stand alone 核心概念算子链任务槽 窗口窗口**窗口的目的与作用****时间窗口&#xff08;Time Windows&#xff…

jenkins 部署 vue 项目

jenkins 部署 vue 项目 环境 系统&#xff1a;CentOS7.9 Jenkins&#xff1a;最新LTS版本 nginx: 1.24.x gitLab: 打包机&#xff1a;jenkins所在服务器 目标机器&#xff1a;nginx所在服务器 jenkins部署配置 关键脚本 #node -v #已经安装node_module就无需执行install安…