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

STL之list的使用(超详解)

目录

一、list的介绍及使用

1.1 list的介绍 

1.2 list的使用 

1.2.1 list的构造 

1.2.2  iterator的使用 

1.2.3capacity(容量相关) 

1.2.4  element access(元素访问) 

1.2.5 modifiers(链表修改) 

1.2.6 operation(对链表的一些操作) 

二、从功能角度迭代器分类: 


 

💓 博客主页:C-SDN花园GGbond

⏩ 文章专栏:玩转c++

一、list的介绍及使用

1.1 list的介绍 

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

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

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

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

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

 

1.2 list的使用 

list文档 list 在实际中非常重要,在实际中我们熟悉常用的接口就可以,下面列出了需要我们重点掌握的接口。

1.2.1 list的构造 

 

size_type 表示一个无符号整数类型,value_type 是 list 的第一个模板参数,也就是要存储的数据类型。使用迭代器区间的构造函数是函数模板,只要是满足 Input 类型的迭代器都可以使用该构造函数。 

1.2.2  iterator的使用 

 

 

注意:begin 与 end 为正向迭代器,对迭代器执行 ++ 操作,迭代器向后移动。rbegin 与 rend 为反向迭代器,对迭代器执行 ++ 操作,迭代器向前移动。由于 list 的底层物理空间并不连续,所以 list 的迭代器不再是原生指针,并且 list 的迭代器没有对 + 和 - 进行重载,只重载了 ++ 和 – ,因为空间不连续,重载 + 会比较复杂。即 l.begin() + 5 是不被允许的。

 

#include<iostream>
using namespace std;
#include<list>
void print_list(list<int>& lt)
{
    list<int>::iterator it = lt.begin();
   // 用迭代器方式打印l2中的元素
    while (it != lt.end())
    {
        cout << *it << " ";
        it++;
    }
    cout << endl;

    
    for (int& e : lt) // C++11范围for的方式遍历
    {
        cout << e << " ";
    }
    cout << endl;
    //反向迭代器
    list<int>::reverse_iterator rit = lt.rbegin();
    while (rit != lt.rend())
    {
        cout << *rit << " ";
        rit++;
    }
    cout << endl;
}
void TestList1()
{
    list<int> l1; // 构造空的l1
    list<int> l2(4, 100);// l2中放4个值为100的元素
    list<int> l3(l2.begin(), l2.end());// 用l2的[begin(), end())左闭右开的区间构造l3
    list<int> l4(l3);// 用l3拷贝构造l4
    int arr[] = { 1,2,3,4,5,6 };
    list<int> l5(arr, arr + sizeof(arr) / sizeof(arr[0])); // 以数组为迭代器区间构造l5
    list<int> l6{ 9,8,7,6 };// 列表格式初始化C++11
    print_list(l1);
    print_list(l2);
    print_list(l3);
    print_list(l4);
    print_list(l5);
    print_list(l6); 
}

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

 

1.2.3capacity(容量相关) 

 

void TestList2()
{
    list<int> l1; // 构造空的l1
    list<int> l2(4, 100);// l2中放4个值为100的元素
    cout << l1.size() << endl;
    cout << l2.size()<<endl;

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

 

 

1.2.4  element access(元素访问) 

 

1.2.5 modifiers(链表修改) 

 

insert 插入元素并不会导致迭代器失效,例如:相较于 vector 中的 insert,list 中的 insert 并不会去扩容挪动数据,而 vector 中的 insert 可能会进行扩容挪动数据,最终导致迭代器失效。list 中的删除元素接口会导致迭代器失效,失效的只有指向被删除节点的迭代器,其他迭代器不会受到影响。

void TestList3()
{
    list<int> l1; // 构造空的l1
    list<int> l2(4, 100);// l2中放4个值为100的元素
    cout << l1.size() << endl;
    cout << l2.size()<<endl;
    l1.push_front(22);
    l1.push_front(11);
    print_list(l1);
    l2.insert(l2.begin(), 99);
    print_list(l2);
    list<int>::iterator it = l2.begin();
    int k = 3;
    while (k--)
    {
        it++;
    }
    l2.insert(it, 0);
    print_list(l2);
    l2.clear();
    print_list(l2);
    cout << "**********************";
}
int main()
{
	TestList3();
	return 0;
}

 

 

1.2.6 operation(对链表的一些操作) 

 

 

splice() 函数主要用于在列表中进行元素的转移操作。 它可以将一个列表中的部分或全部元素转移到另一个列表中。可以指定要转移的元素范围以及目标插入位置等,实现了高效灵活的元素移动和重组。 

 

 

remove函数相当于一直遍历列表,然后erase删除指定元素。 

 

unique 函数主要用于移除列表中相邻的重复元素。它使得容器中只保留不重复的元素序列,但需要注意的是,它并不保证完全去除所有重复元素,只是处理相邻的重复项,通常也需要结合其他操作来实现完全去重。 

 

merge()函数主要用于将两个已排序的序列合并成一个新的已排序序列。 它会按照排序顺序将一个序列中的元素与另一个序列中的元素合理地组合在一起,形成一个合并后的有序序列。需要注意的是,在合并之前,两个源序列本身需要是已经排序好的。 

 

链表逆置可以使用 list 自身的接口,也可以使用算法库中的 reverse,二者没有什么区别。链表排序只能使用 list 自身的 sort() 接口(底层是利用归并排序),不能使用算法库的 sort,因为算法库中的 sort 底层是通过快排来实现的,而快排中会涉及到三数取中需要迭代器 - 迭代器,链表不能很好的支持。虽然链表提供了排序接口,但是用链表对数据排序意义不大,效率太低了,更希望用 vector 来对数据进行排序。 

 

二、从功能角度迭代器分类: 

迭代器类型功能
单向(InputIterator)支持 ++
双向(BidirectionalItreator)支持 ++/- -
随机(RandomAccessIterator)支持 ++ / - - / + / -

其中 forward_listunordered_xxx 都是单向迭代器;listmapset 都是双向迭代器;vectorstringdeque 都是随机迭代器。对迭代器的这种分类方式,是由容器的底层结构来决定的。 

算法库中也有一个sort()函数,但是其支持的是随机迭代器,而list是一种双向迭代器,所以list无法调用算法库中的sort()

相关文章:

  • 【时间序列】Patch:到底是什么?
  • 【极光 Orbit•STC8A-8H】03. 小刀初试:点亮你的LED灯
  • 数字信号处理之信号功率谱计算welch方法(分段加窗平均周期图)、Bartlett方法(周期图)(Python)
  • 以网络形式启动Linux系统后,通过挂载(mount)的方式,将eMMC存储器中旧的根文件系统所在逻辑2分区格式化,并解压新的根文件系统到逻辑2分区
  • 【Linux文件IO】标准IO详情(1)
  • kubernetes——part3-5 核心概念 Service
  • 知识图谱相关的Terse RDF Triple Language 文件格式介绍
  • 如何提高域名解析速度?
  • yolov8 画不同训练的损失函数对比图
  • 电力场景绝缘子缺陷分割数据集labelme格式1585张4类别
  • 【STM32MP157系统移植】3.TF-A目录结构
  • 热图回归(Heatmap Regression)
  • 【人工智能】卷积神经网络的奥秘:深度学习的视觉革命
  • 手太阴肺经之经渠穴
  • 【c++】平移字符串
  • 百问网提供的烧写工具将各镜像文件烧写到eMMC存储器的各脚本的解析
  • AI赋能医疗:仅靠想象就能控制机械臂,近屿智能AI培训新选择
  • 高并发下订单库存防止超卖策略
  • 【Python】为什么要写__init__.py
  • 通义万相2.1开源版本地化部署攻略,生成视频再填利器
  • 营业执照如何办理/抚州seo外包
  • 营销型网站建设费用/建立网站有哪些步骤
  • 财经网站源码 织梦/每日财经最新消息
  • 网站设计的基本方法/百度云服务器官网
  • 网站做子页面怎么做的/网站统计分析平台
  • 网页设计排版布局/seo专员工作容易学吗