C++STL之list的使用详解

embedded/2024/9/23 8:46:50/

一、简介

1、底层list为双向链表,即struct中包含一个数据和两个指针,分别指向前一个节点和后一个节点,在堆上分配空间,每插入一个元素都会分配空间,每删除一个元素都会释放空间

2、性能

① 访问:随机访问性能很差,只能快速访问头尾节点

② 插入:很快,一般是常数开销

③ 删除:很快,一般是常数开销

3、适用场景list 拥有一段不连续的内存空间,如果需要高效的插入和删除,而不关心随机访问,则应使用 list

二、list的基本操作

1、初始化

#include<iostream>
#include<map>
#include<string>
#include<list>
using namespace std;
int main()
{std::list<int> my_list; // 构造空链表my_list.push_back(1); // 尾部插入数据1my_list.push_back(2); // 尾部插入数据2my_list.push_back(3); // 尾部插入数据3std::list<int> my_list1(3, 5); // 构造3个5的链表std::list<int> my_list2(my_list1.begin(), my_list1.end()); // 拷贝构造
}

2、插入数据

① push_front() 头部插入元素

push_front()函数用于将一个新的元素插入到链表的开头位置, 时间复杂度为O(1)。在双向链表中插入元素到开头位置的操作只涉及指针的重新链接,不需要移动其他元素

my_list.push_front(0); // 头插数据0
② push_back() 尾部插入元素

push_back()函数用于将一个新的元素插入到链表尾部, 时间复杂度为O(1)

my_list.push_back(4);
③ insert() 插入元素

insert()函数在 position 位置中插入值为val的元素。

插入单个数据。第一个参数为迭代器,即插入的位置,第二个参数是插入的数据。

// 尾部插入元素5
my_list.insert(my_list.end(), 5);

插入多个相同数据。第一个参数为迭代器,即插入的位置,第二个参数是插入的数据个数,第三个参数是插入的数据。

// 在尾部插入2个6
my_list.insert(my_list.end(), 2, 6);

插入多个数据。第一个参数为迭代器,即插入的位置,第二个参数是迭代器,需要插入元素初始位置,第三个参数是迭代器,需要插入元素的结束位置

/* 在my_list尾部插入3个5 */
std::list<int> my_list1(3, 5); // 构造3个5的链表
my_list.insert(my_list.end(), my_list1.begin(), my_list1.end());

3、删除数据

① pop_front() 头删元素

pop_front()函数用于删除链表中的第一个元素,时间复杂度为O(1)

my_list.pop_front();
② pop_back() 尾删元素
my_list.pop_back();
③ erase()删除数据

erase()函数用于删除链表中数据, 返回值是当前删除元素位置的下一个迭代器。

删除单个元素,参数为迭代器。

list<int>::iterator pos = my_list.begin(); // 第一个元素为0
if (pos != my_list.end())
{auto it = my_list.erase(pos);std::cout << "next: " << *it << std::endl; // 当前第一个元素为1
}

删除多个元素,两个参数均为迭代器,分别为初始位置和结束位置。

my_list.erase(my_list.begin(), my_list.end());
④ clear() 删除所有数据
my_list.clear();
⑤ remove() 删除元素

list中删除元素,remove(val) 删除所有为val的元素

4、修改数据

① assign() 替换/赋值

assign(n,val); 

将当前列表中所有元素替换为n个T类型的val

my_list.assign(6, 1);

assign(l2.begin(),l2.end());

将12列表中的从l2.begin()到l2.end()之间的数值赋值给当前列表l1

my_list.assign(my_list1.begin(), my_list1.end());
② swap() 交换

交换两个链表数据,两种用法均可。

my_list.swap(my_list1);
swap(my_list, my_list1);
③ reverse() 反转

反转链表中数据。

my_list.reverse();
④ merge() 合并

l1.merge(l2); 默认升序

l1.merge(l2,greater<int>()); 升序排序

l1.merge(l2,less<int>()); 降序排序

合并两个链表。调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序

my_list.merge(my_list1);
⑤ resize() 

调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除。如果n比list原来的长度长,那么默认超出的部分元素置为0。

my_list.resize(2); // 大小修改为2个元素,多的元素删除

也可以用resize(n, m)的方式将超出的部分赋值为m。

my_list.resize(10, 0); // 大小修改为10个元素,多的赋值为0

5、查找数据

① front() 获取头部元素
my_list.front();
② back() 获取尾部元素
my_list.back();
③ 迭代器
for (auto const& v : my_list)
{std::cout << "v:" << v << std::endl;
}

6、其他用法

① sort() 排序

sort函数用于排序,默认升序

my_list.sort();
② size() 获取大小
int size = my_list.size();
③ unique() 去重

去重就是对该链表对象进行遍历,将元素值相同的多个元素进行删除,只保留唯一一个值节点

my_list.unique();

ok,今天分享就到这里了。

如果觉得分享对你有所帮助的话,记得点赞哦!

主页还有其他相关文章,欢迎一起学习,一起进步~


http://www.ppmy.cn/embedded/103503.html

相关文章

HTML5CSS3-CSS3选择器

一、属性选择器(可以根据特定条件选择标签) input[type^but] 选中type以but为开头的标签 input[type$word] 选中type以word为结尾的标签 input[type*t] 选中type出现t字母的全部标签 二、伪类选择器 li:empty {} 选中没有嵌套内容的li标签 li:not(.…

计算机毕业设计选题推荐-二手物品回收系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【ESP-IDF FreeRTOS】队列管理

先包含下头文件。 #include "freertos/queue.h" 队列大家应该不陌生&#xff0c;就是一个先进先出的容器。用在FreeRTOS里用途就多了。 首先是可以让任务与任务之间以及中断之间通信&#xff0c;任务A把数据塞进队列再让任务B取出&#xff0c;这样就可以传递数据了…

ARCGIS 纸质小班XY坐标转电子要素面(2)

本章用于说明未知坐标系情况下如何正确将XY转要素面 背景说明 现有资料&#xff1a;清除大概位置&#xff0c;纸质小班图&#xff0c;图上有横纵坐标&#xff0c;并已知小班XY拐点坐标&#xff0c;但未知坐标系。需要上图 具体操作 大部分操作同这边文章ARCGIS 纸质小班XY…

如何实现OpenHarmony的OTA升级

OTA简介 随着设备系统日新月异&#xff0c;用户如何及时获取系统的更新&#xff0c;体验新版本带来的新的体验&#xff0c;以及提升系统的稳定性和安全性成为了每个厂商都面临的严峻问题。OTA&#xff08;Over the Air&#xff09;提供对设备远程升级的能力。升级子系统对用户…

Dataworks_PySpark开发流程

PySpark是由Spark官方开发的Python语言第三方库&#xff0c;Python开发者可以通过使用python语言来编写Spark程序和SparkSQL完成开发。 之所以采用PySpark而不采用Java/Scala&#xff0c;是由于&#xff1a; Dataworks可通过将代码在线写入DataWorks Python资源的方式&#xf…

Spring Boot3 建立一个后台系统的架构框架

用Spring Boot 3 建立一个后台系统的架构&#xff0c; 前端与后端分离在不同的模块中&#xff0c; 并支持权限管理和监控功能&#xff0c;设计一个多模块项目。 每个模块承担特定的职责&#xff0c;单一职责&#xff0c;整个系统具备良好的扩展性、维护性和独立性。 下面是一个…

docker-compose 编排 lnmp 集群

1、docker-compose.yml ⽂件 [rootdoc lnmp]# vim docker-compose.yml version: 2 volumes: mysql-conf: php-conf: networks: lnmp_net: external: true services: nginx: image: nginx container_name: nginx-lnmp hostname: nginx-lnmp privileged: true por…